minor speedup tweaks
#[inline]
/// XOR two byte arrays, outputting the result.
pub fn xor(a: &[u8], b: &[u8]) -> Vec<u8> {
- a.iter()
- .zip(b.iter())
- .map(|(a, b)| a ^ b)
- .collect::<Vec<u8>>()
+ a.iter().zip(b.iter()).map(|(a, b)| a ^ b).collect()
}
#[inline]
@@ -22,39 +19,36 @@ pub fn xor_n(a: &[u8], b: &[u8], n: usize) -> Vec<u8> {
.iter()
.zip(b[0..n].iter())
.map(|(a, b)| a ^ b)
- .collect::<Vec<u8>>()
+ .collect()
}
/// XOR two byte arrays in place.
#[inline]
pub fn xor_inplace(a: &mut [u8], b: &[u8]) {
- for i in 0..a.len() {
- a[i] ^= b[i];
+ for (a, b) in a.iter_mut().zip(b.iter()) {
+ *a ^= *b;
}
}
#[inline]
/// XOR two byte arrays up to `n` bytes in place.
pub fn xor_inplace_n(a: &mut [u8], b: &[u8], n: usize) {
- for i in 0..n {
- a[i] ^= b[i];
+ for (a, b) in a[0..n].iter_mut().zip(b.iter()) {
+ *a ^= *b;
}
}
#[inline]
/// AND two byte arrays, outputting the result.
pub fn and(a: &[u8], b: &[u8]) -> Vec<u8> {
- a.iter()
- .zip(b.iter())
- .map(|(a, b)| a & b)
- .collect::<Vec<u8>>()
+ a.iter().zip(b.iter()).map(|(a, b)| a & b).collect()
}
#[inline]
/// AND two byte arrays in place.
pub fn and_inplace(a: &mut [u8], b: &[u8]) {
- for i in 0..a.len() {
- a[i] &= b[i];
+ for (a, b) in a.iter_mut().zip(b.iter()) {
+ *a &= *b;
}
}
@@ -62,6 +56,25 @@ pub fn and_inplace(a: &mut [u8], b: &[u8]) {
mod tests {
use super::*;
+ #[test]
+ fn test_xor() {
+ let v = (0..128).map(|_| rand::random::<u8>()).collect::<Vec<u8>>();
+ let v_ = (0..128).map(|_| rand::random::<u8>()).collect::<Vec<u8>>();
+ let v__ = xor(&v, &v_);
+ let v___ = xor(&v__, &v_);
+ assert_eq!(v___, v);
+ }
+
+ #[test]
+ fn test_xor_inplace() {
+ let mut v = (0..128).map(|_| rand::random::<u8>()).collect::<Vec<u8>>();
+ let goal = v.clone();
+ let v_ = (0..128).map(|_| rand::random::<u8>()).collect::<Vec<u8>>();
+ xor_inplace(&mut v, &v_);
+ xor_inplace(&mut v, &v_);
+ assert_eq!(v, goal);
+ }
+
#[test]
fn test_and() {
let v = (0..128).map(|_| rand::random::<u8>()).collect::<Vec<u8>>();
