cryptopals

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs

1-1.rs (1423B)


      1 use cryptopals::utils::read_buffer;
      2 
      3 fn main() -> Result<(), Box<dyn std::error::Error>> {
      4     let hex_input = read_buffer()?;
      5     let bytes = hex_to_bytes(&hex_input);
      6     let base64_output = bytes_to_base64(&bytes);
      7 
      8     println!("{}", base64_output);
      9 
     10     Ok(())
     11 }
     12 
     13 const BASE64_TABLE: &[u8; 64] = b"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
     14 
     15 fn hex_to_bytes(hex: &str) -> Vec<u8> {
     16     hex.as_bytes()
     17         .chunks(2)
     18         .map(|chunk| {
     19             let s = std::str::from_utf8(chunk).unwrap();
     20             u8::from_str_radix(s, 16).expect("Invalid hex")
     21         })
     22         .collect()
     23 }
     24 
     25 fn bytes_to_base64(bytes: &[u8]) -> String {
     26     let mut result = String::with_capacity((bytes.len() + 2) / 3 * 4);
     27 
     28     for chunk in bytes.chunks(3) {
     29         let b0 = chunk[0] as usize;
     30         let b1 = chunk.get(1).map(|&b| b as usize).unwrap_or(0);
     31         let b2 = chunk.get(2).map(|&b| b as usize).unwrap_or(0);
     32 
     33         let n = (b0 << 16) | (b1 << 8) | b2;
     34 
     35         result.push(BASE64_TABLE[(n >> 18) & 0x3F] as char);
     36         result.push(BASE64_TABLE[(n >> 12) & 0x3F] as char);
     37 
     38         if chunk.len() > 1 {
     39             result.push(BASE64_TABLE[(n >> 6) & 0x3F] as char);
     40         } else {
     41             result.push('=');
     42         }
     43 
     44         if chunk.len() > 2 {
     45             result.push(BASE64_TABLE[n & 0x3F] as char);
     46         } else {
     47             result.push('=');
     48         }
     49     }
     50     result
     51 }