math.big: add from_bytes function (#11213)
							parent
							
								
									90b25e7a4b
								
							
						
					
					
						commit
						19abe8c750
					
				| 
						 | 
				
			
			@ -118,6 +118,28 @@ pub fn from_string(input string) Number {
 | 
			
		|||
	return n
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// from_bytes converts an array of bytes (little-endian) to a big.Number.
 | 
			
		||||
// Higher precedence bytes are expected at lower indices in the array.
 | 
			
		||||
pub fn from_bytes(input []byte) ?Number {
 | 
			
		||||
	if input.len > 128 {
 | 
			
		||||
		return error('input array too large. big.Number can only hold up to 1024 bit numbers')
 | 
			
		||||
	}
 | 
			
		||||
	// pad input
 | 
			
		||||
	mut padded_input := []byte{len: ((input.len + 3) & ~0x3) - input.len, cap: (input.len + 3) & ~0x3, init: 0x0}
 | 
			
		||||
	padded_input << input
 | 
			
		||||
	// combine every 4 bytes into a u32 and insert into n.array
 | 
			
		||||
	mut n := Number{}
 | 
			
		||||
	for i := 0; i < padded_input.len; i += 4 {
 | 
			
		||||
		x3 := u32(padded_input[i])
 | 
			
		||||
		x2 := u32(padded_input[i + 1])
 | 
			
		||||
		x1 := u32(padded_input[i + 2])
 | 
			
		||||
		x0 := u32(padded_input[i + 3])
 | 
			
		||||
		val := (x3 << 24) | (x2 << 16) | (x1 << 8) | x0
 | 
			
		||||
		n.array[(padded_input.len - i) / 4 - 1] = val
 | 
			
		||||
	}
 | 
			
		||||
	return n
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// .int() converts (a small) big.Number `n` to an ordinary integer.
 | 
			
		||||
pub fn (n &Number) int() int {
 | 
			
		||||
	r := C.bignum_to_int(n)
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -165,3 +165,17 @@ fn test_bytes_trimmed() {
 | 
			
		|||
	assert big.from_int(1024).bytes_trimmed() == [byte(0x00), 0x04]
 | 
			
		||||
	assert big.from_int(1048576).bytes_trimmed() == [byte(0x00), 0x00, 0x10]
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
fn test_from_bytes() ? {
 | 
			
		||||
	assert big.from_bytes([]) ?.hexstr() == '0'
 | 
			
		||||
	assert big.from_bytes([byte(0x13)]) ?.hexstr() == '13'
 | 
			
		||||
	assert big.from_bytes([byte(0x13), 0x37]) ?.hexstr() == '1337'
 | 
			
		||||
	assert big.from_bytes([byte(0x13), 0x37, 0xca]) ?.hexstr() == '1337ca'
 | 
			
		||||
	assert big.from_bytes([byte(0x13), 0x37, 0xca, 0xfe]) ?.hexstr() == '1337cafe'
 | 
			
		||||
	assert big.from_bytes([byte(0x13), 0x37, 0xca, 0xfe, 0xba]) ?.hexstr() == '1337cafeba'
 | 
			
		||||
	assert big.from_bytes([byte(0x13), 0x37, 0xca, 0xfe, 0xba, 0xbe]) ?.hexstr() == '1337cafebabe'
 | 
			
		||||
	assert big.from_bytes([]byte{len: 128, init: 0x0}) ?.hexstr() == '0'
 | 
			
		||||
	if x := big.from_bytes([]byte{len: 129, init: 0x0}) {
 | 
			
		||||
		return error('expected error, got $x')
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in New Issue