From 70f778ad5516a2873cc869d58f2762ccb09e4050 Mon Sep 17 00:00:00 2001 From: Phaiax Date: Sun, 13 Mar 2016 11:20:07 +0100 Subject: [PATCH] more playing around --- crates/ramp | 2 +- src/base62.rs | 141 ++++++++++++++++++++++++++++++++++++++++++++------ src/lib.rs | 12 ++++- 3 files changed, 137 insertions(+), 18 deletions(-) diff --git a/crates/ramp b/crates/ramp index 9d704fc..4092f95 160000 --- a/crates/ramp +++ b/crates/ramp @@ -1 +1 @@ -Subproject commit 9d704fc109cd4b4dad0541588e8300cdbd5dcdbd +Subproject commit 4092f9556842672a62278a102bb3146b29c943c7 diff --git a/src/base62.rs b/src/base62.rs index f571709..7db5cb5 100644 --- a/src/base62.rs +++ b/src/base62.rs @@ -17,6 +17,7 @@ use ramp::ll::limb::Limb; use std::mem::transmute; use byteorder::{ByteOrder, BigEndian, ReadBytesExt}; use std::io::Cursor; +use std::io::Read; use std::ptr::Unique; use alloc::raw_vec::RawVec; @@ -33,6 +34,15 @@ pub fn decode(base62 : String) -> Vec { */ +/// +/// +/// NUMCHARS_FOR_NUMBYTES[num_input_bytes <= 32] +static NUMCHARS_FOR_NUMBYTES : [u8;33] = [ 0, 2, 3, 5, 6, 7, 9, 10, 11, + 13, 14, 15, 17, 18, 19, 21, 22, 23, 25, 26, + 27, 29, 30, 31, 33, 34, 35, 37, 38, + 39, 41, 42, 43]; + + pub fn as_u32_mut<'a>(bytes : &'a mut [u8; 4]) -> &'a mut u32 { unsafe { transmute(bytes as *const [u8; 4] as *const u8 as *const u32) } } @@ -52,30 +62,83 @@ pub fn bigint_from_cursor(reader : &mut Cursor) -> Int { } #[cfg(target_pointer_width = "64")] -pub fn bigint_from_cursor(reader : &mut Cursor<&[u8]>) -> Int { - +pub fn bigint_from_cursor(reader : &mut Cursor<&[u8]>) -> (Int, usize) { + let mut r : Int; // bigint has to represent 32 bytes, that makes 32/8=4 limbs on 64bit machines - let mut heap_limbs : Box<[Limb; 4]> = Box::new([Limb(0), Limb(0), Limb(0), Limb(0)]); + //let mut heap_limbs : Box<[Limb; 4]> = Box::new([Limb(0), Limb(0), Limb(0), Limb(0)]); + + // 32 bytes in Big Endian: { msbyte:[msbit lsbit] .... lsbyte[] } + + let mut it = (*reader).by_ref().bytes(); - if let Ok(next_limb) = (*reader).read_u64::() { - heap_limbs[0] = Limb(next_limb); + if let Some(next_u8) = it.next() { + r = Int::from(next_u8.unwrap()); + } else { + r = Int::zero(); + return (r, 0); } - if let Ok(next_limb) = (*reader).read_u64::() { - heap_limbs[1] = Limb(next_limb); + + for i in 1..32 { // the other bytes + if let Some(next_u8) = it.next() { + r = r << 8; + r = r + Int::from(next_u8.unwrap()); + } else { + return (r, i); + } } - if let Ok(next_limb) = (*reader).read_u64::() { - heap_limbs[2] = Limb(next_limb); + (r, 32) +} +//porEeh8cn4QrWbhKmFSNts5zn00MWVux8d4G112ipE0 + +#[inline] +pub fn base62_single(i : Int, s : &mut String) { + if i < 10 { + s.push( (b'0' + u8::from(&i)) as char); + } else if i < 36 { + s.push( (b'A' + u8::from(&i) - 10) as char); + } else if i < 62 { + s.push( (b'a' + u8::from(&i) - 36) as char); + } else { + panic!("Programm logic error."); } - if let Ok(next_limb) = (*reader).read_u64::() { - heap_limbs[3] = Limb(next_limb); +} + + + +pub fn base62_block(i : Int, l : usize) -> String { + let mut ret = String::with_capacity(43); + let base = Int::from(62); + let mut quot = i; + let mut rem = Int::zero(); + for _ in 0..NUMCHARS_FOR_NUMBYTES[l] { + let (quot2, rem) = quot.divmod(&base); + base62_single(rem, &mut ret); + // 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz + quot = quot2; } + ret +} - let mut limbs : RawVec = RawVec::from_box(heap_limbs); - let mut ptr: Unique = Unique::new(limbs.ptr()); - Int { ptr: ptr, size: 4, cap: 4 } +pub fn base62_stream(reader : &mut Cursor<&[u8]>) -> String { + let mut ret = String::with_capacity(20000); + loop { + let (bigint, len) = bigint_from_cursor(&mut reader.by_ref()); + if len == 0 { + break; + } + ret.push_str(&base62_block(bigint, len)); + } + + ret } +/* + + + +*/ + #[cfg(test)] #[allow(unused_variables)] @@ -84,13 +147,59 @@ mod test { use std::mem::transmute; use byteorder::{ByteOrder, BigEndian, ReadBytesExt}; use std::io::Cursor; + use ramp::Int; + + #[test] - fn bigints() { + fn test_base62_single() { + fn c2b62(i : u8) -> String { + let mut s = String::with_capacity(1); + base62_single(Int::from(i), &mut s); + s + } + assert_eq!("0", c2b62(0)); + assert_eq!("1", c2b62(1)); + assert_eq!("9", c2b62(9)); + assert_eq!("A", c2b62(10)); + assert_eq!("B", c2b62(11)); + assert_eq!("Z", c2b62(35)); + assert_eq!("a", c2b62(36)); + assert_eq!("z", c2b62(61)); + } + + #[test] + fn test_base62_stream() { let three_blocks = (1..96).collect::>(); - let bytes : [u8] = three_blocks[..]; + let bytes : &[u8] = &three_blocks[0..95]; + let mut c = Cursor::new(bytes); + println!("{:?}", base62_stream(&mut c)); + assert_eq!(1, 2); + } + #[test] + fn test_base62_block() { + let three_blocks = (1..96).collect::>(); + let bytes : &[u8] = &three_blocks[0..95]; + let mut c = Cursor::new(bytes); + let (i1, l1) = bigint_from_cursor(&mut c); + assert_eq!(base62_block(i1, l1), "123"); + } + + + #[test] + fn bigints() { + let three_blocks = (1..96).collect::>(); + let bytes : &[u8] = &three_blocks[0..95]; + let mut c = Cursor::new(bytes); + let (i1, l1) = bigint_from_cursor(&mut c); + let (i2, l2) = bigint_from_cursor(&mut c); + let (i3, l3) = bigint_from_cursor(&mut c); + println!("{:?} read: {:?}", i1, l1); + println!("{:?} read: {:?}", i2, l2); + println!("{:?} read: {:?}", i3, l3); + assert_eq!("1", i1.to_str_radix(10, true)); } diff --git a/src/lib.rs b/src/lib.rs index 041a664..2a04394 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -10,10 +10,20 @@ extern crate alloc; //mod headerpacket; -mod base62; +//mod base62; + +// step 1: iter through input string.as_bytes() and copy u8 to extra array if not whitespace +// thereby convert from letter to associated number +// step 2: for each full 42 byte slice: +// step 3: create Int from Base #[cfg(test)] mod test { + + #[test] + fn test_base62_to_ + + #[test] fn it_works() { }