Created
June 21, 2021 18:26
-
-
Save commander-trashdin/df0c367bb8abb2512efe3f46c2b66d37 to your computer and use it in GitHub Desktop.
xorsism
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| /// A munger which XORs a key with some data | |
| use std::borrow::Borrow; | |
| #[derive(Clone)] | |
| pub struct Xorcism<'a> { | |
| key: &'a [u8], | |
| position: usize, | |
| } | |
| pub trait Captures<'a> {} | |
| impl<'a, T: ?Sized> Captures<'a> for T {} | |
| impl<'a> Xorcism<'a> { | |
| /// Create a new Xorcism munger from a key | |
| /// | |
| /// Should accept anything which has a cheap conversion to a byte slice. | |
| pub fn new<Key>(key: &'a Key) -> Xorcism<'a> | |
| where | |
| Key: AsRef<[u8]> + ?Sized + 'a, | |
| { | |
| let key: &'a [u8] = key.as_ref(); | |
| Self { key, position: 0 } | |
| } | |
| /// XOR each byte of the input buffer with a byte from the key. | |
| /// | |
| /// Note that this is stateful: repeated calls are likely to produce different results, | |
| /// even with identical inputs. | |
| pub fn munge_in_place(&mut self, data: &mut [u8]) { | |
| for c in data.iter_mut() { | |
| *c ^= self.key[self.position]; | |
| self.position += 1; | |
| self.position %= self.key.len() | |
| } | |
| } | |
| /// XOR each byte of the data with a byte from the key. | |
| /// | |
| /// Note that this is stateful: repeated calls are likely to produce different results, | |
| /// even with identical inputs. | |
| /// | |
| /// Should accept anything which has a cheap conversion to a byte iterator. | |
| /// Shouldn't matter whether the byte iterator's values are owned or borrowed. | |
| pub fn munge<'c, Data>(&'a mut self, data: &'c Data) | |
| -> impl Iterator<Item = u8> + Captures<'a> + 'c | |
| where | |
| Data: IntoIterator, | |
| Data::IntoIter: 'c, | |
| Data::Item: Borrow<u8>, | |
| { | |
| data.into_iter().map(move |value| { | |
| let pos = self.position; | |
| self.position += 1; | |
| self.position %= self.key.len(); | |
| value.borrow() ^ self.key[pos] | |
| }) | |
| } | |
| } |
Using key as Vec<&u8> is probably half-cheating??
...but I could even use std::iter::Cycle instead of vec and ugly handwritten self._next_cycled()
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
This is 300iq:
knowing this everything else is doable: