math.big: add from_bytes function (#11213)
							parent
							
								
									90b25e7a4b
								
							
						
					
					
						commit
						19abe8c750
					
				|  | @ -118,6 +118,28 @@ pub fn from_string(input string) Number { | ||||||
| 	return n | 	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.
 | // .int() converts (a small) big.Number `n` to an ordinary integer.
 | ||||||
| pub fn (n &Number) int() int { | pub fn (n &Number) int() int { | ||||||
| 	r := C.bignum_to_int(n) | 	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(1024).bytes_trimmed() == [byte(0x00), 0x04] | ||||||
| 	assert big.from_int(1048576).bytes_trimmed() == [byte(0x00), 0x00, 0x10] | 	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