Cleaning up some XOR things
This commit is contained in:
parent
fb457ac1ab
commit
1e1bd0c7c1
1 changed files with 7 additions and 9 deletions
16
src/xor.rs
16
src/xor.rs
|
@ -1,4 +1,3 @@
|
||||||
use std::f32;
|
|
||||||
use std::iter;
|
use std::iter;
|
||||||
|
|
||||||
pub type FixedXOR<T, U> = iter::Map<iter::Zip<T, U>, fn((u8, u8)) -> u8>;
|
pub type FixedXOR<T, U> = iter::Map<iter::Zip<T, U>, fn((u8, u8)) -> u8>;
|
||||||
|
@ -34,6 +33,7 @@ impl<'a, T> SingleByteXORable<T> for T
|
||||||
mod tests {
|
mod tests {
|
||||||
use super::*;
|
use super::*;
|
||||||
use hex::{HexDecodable, HexEncodable};
|
use hex::{HexDecodable, HexEncodable};
|
||||||
|
use std::f32;
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn cryptopals() {
|
fn cryptopals() {
|
||||||
|
@ -55,12 +55,9 @@ mod tests {
|
||||||
];
|
];
|
||||||
|
|
||||||
fn letter_freq_score(input: &str) -> f32 {
|
fn letter_freq_score(input: &str) -> f32 {
|
||||||
let mut freqs: Vec<f32> = iter::repeat(0.0f32).take(26).collect();
|
let mut freqs: Vec<f32> = iter::repeat(0f32).take(26).collect();
|
||||||
let mut num_alphabetic_chars = 0f32;
|
let mut num_alphabetic_chars = 0f32;
|
||||||
for c in input.chars() {
|
for c in input.chars().filter(char::is_ascii_alphabetic) {
|
||||||
if !c.is_ascii_alphabetic() {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
num_alphabetic_chars += 1f32;
|
num_alphabetic_chars += 1f32;
|
||||||
let c = c.to_ascii_uppercase();
|
let c = c.to_ascii_uppercase();
|
||||||
freqs[c as usize - 'A' as usize] += 1f32;
|
freqs[c as usize - 'A' as usize] += 1f32;
|
||||||
|
@ -69,10 +66,11 @@ mod tests {
|
||||||
println!("freqs:{:?}", freqs);
|
println!("freqs:{:?}", freqs);
|
||||||
// Calculate chi-squared for this string, comparing actual frequencies vs. English letter
|
// Calculate chi-squared for this string, comparing actual frequencies vs. English letter
|
||||||
// frequencies.
|
// frequencies.
|
||||||
|
// https://en.wikipedia.org/wiki/Letter_frequency
|
||||||
|
// https://crypto.stackexchange.com/questions/30209/developing-algorithm-for-detecting-plain-text-via-frequency-analysis
|
||||||
let expected_freqs = ENGLISH_LETTER_FREQS.iter().map(|x| x * num_alphabetic_chars);
|
let expected_freqs = ENGLISH_LETTER_FREQS.iter().map(|x| x * num_alphabetic_chars);
|
||||||
let score = freqs.into_iter()
|
let score = freqs.into_iter()
|
||||||
.zip(expected_freqs.into_iter())
|
.zip(expected_freqs)
|
||||||
.inspect(|&(obs, exp)| println!("obs:{}, exp:{}", obs, exp))
|
|
||||||
.fold(0f32, |acc, (obs, exp)| acc + ((obs - exp).powf(2.0) / exp));
|
.fold(0f32, |acc, (obs, exp)| acc + ((obs - exp).powf(2.0) / exp));
|
||||||
score
|
score
|
||||||
}
|
}
|
||||||
|
@ -86,7 +84,7 @@ mod tests {
|
||||||
for key in 32u8..127 {
|
for key in 32u8..127 {
|
||||||
let possible_output = input.chars().hex_decoded()
|
let possible_output = input.chars().hex_decoded()
|
||||||
.single_byte_xor(key)
|
.single_byte_xor(key)
|
||||||
.map(|x| char::from(x))
|
.map(char::from)
|
||||||
.collect::<String>();
|
.collect::<String>();
|
||||||
let score = letter_freq_score(&possible_output);
|
let score = letter_freq_score(&possible_output);
|
||||||
println!("{}: {:?} -> {}", key, possible_output, score);
|
println!("{}: {:?} -> {}", key, possible_output, score);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue