Compare commits
	
		
			1 commit
		
	
	
		
			master
			...
			improved-c
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| 1cb5b59763 | 
					 3 changed files with 27 additions and 7 deletions
				
			
		|  | @ -24,6 +24,28 @@ pub fn english_letter_freqs() -> FreqMap { | |||
|     FreqMap::from_iter(char_strings.zip(ENGLISH_LETTER_FREQS.iter().map(|x| *x))) | ||||
| } | ||||
| 
 | ||||
| struct EnglishLetterSet { | ||||
|     freqs: FreqMap, | ||||
| } | ||||
| 
 | ||||
| impl EnglishLetterSet { | ||||
|     fn new() -> EnglishLetterSet { | ||||
|         EnglishLetterSet { freqs: english_letter_freqs() } | ||||
|     } | ||||
| 
 | ||||
|     fn is_valid(&self, c: char) -> bool { | ||||
|         c.is_ascii_alphabetic() | ||||
|     } | ||||
| 
 | ||||
|     fn is_ignored(&self, c: char) -> bool { | ||||
|         c.is_ascii_whitespace() || c.is_ascii_punctuation() || c.is_ascii_digit() | ||||
|     } | ||||
| 
 | ||||
|     fn frequency_for(&self, c: char) -> f32 { | ||||
|         freqs.get(c.to_uppercase().to_string()).unwrap_or(0f32); | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| pub trait LetterFreq { | ||||
|     fn letter_freqs(&self, lang: &str) -> FreqMap; | ||||
|     fn chi2_freqs(&self, lang: &str) -> f32; | ||||
|  | @ -32,13 +54,10 @@ pub trait LetterFreq { | |||
| impl<'a> LetterFreq for &'a str { | ||||
|     fn letter_freqs(&self, lang: &str) -> FreqMap { | ||||
|         assert_eq!(lang, "en", "only 'en' language is supported rn"); | ||||
|         let english_letters = english_letters(); | ||||
|         let mut freqs = FreqMap::new(); | ||||
|         for c in self.chars() { | ||||
|             let c_str = c.to_uppercase().to_string(); | ||||
|             if english_letters.contains(&c_str) { | ||||
|                 *freqs.entry(c_str).or_insert(0f32) += 1f32; | ||||
|             } | ||||
|             *freqs.entry(c_str).or_insert(0f32) += 1f32; | ||||
|         } | ||||
|         freqs | ||||
|     } | ||||
|  | @ -51,8 +70,8 @@ impl<'a> LetterFreq for &'a str { | |||
|         let freqs = self.letter_freqs(lang); | ||||
|         let english_freqs = english_letter_freqs(); | ||||
|         let num_letters = freqs.values().sum::<f32>(); | ||||
|         let score = english_freqs.into_iter() | ||||
|             .map(|(c, sc)| (freqs.get(&c).map_or(0f32, |c| *c), sc * num_letters)) | ||||
|         let score = freqs.into_iter() | ||||
|             .map(|(c, f)| (f, english_freqs.get(&c).map_or(1e-8, |c| c * num_letters))) | ||||
|             .fold(0f32, |acc, (obs, exp)| acc + ((obs - exp).powf(2.0) / exp)); | ||||
|         score | ||||
|     } | ||||
|  |  | |||
|  | @ -1,4 +1,5 @@ | |||
| use std::iter; | ||||
| use std::slice; | ||||
| 
 | ||||
| pub type FixedByteXOR<T, U> = iter::Map<iter::Zip<T, U>, fn((u8, u8)) -> u8>; | ||||
| pub type SingleByteXOR<T> = FixedByteXOR<T, iter::Repeat<u8>>; | ||||
|  |  | |||
|  | @ -81,7 +81,7 @@ fn s1c4() { | |||
|         let mut best_score = f32::INFINITY; | ||||
|         let mut best_output: Option<String> = None; | ||||
|         for key in 32u8..127 { | ||||
|             let decrypted = decoded.iter().byte_xor(key).map(char::from).collect::<String>(); | ||||
|             let decrypted = decoded.iter().map(|c| *c).byte_xor(key).map(char::from).collect::<String>(); | ||||
|             let score = decrypted.chi2_freqs("en"); | ||||
|             if !score.is_nan() && score < best_score { | ||||
|                 best_score = score; | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue