13 个版本 (破坏性)
| 0.11.0 | 2024年3月6日 |
|---|---|
| 0.10.0 | 2023年11月23日 |
| 0.9.1 | 2023年10月25日 |
| 0.8.0 | 2023年7月23日 |
| 0.1.0 | 2022年7月10日 |
#45 in 加密学
60,283 每月下载量
用于 646 个crate(直接使用4个)
440KB
10K SLoC
bnum
Rust的任意精度、固定大小的有符号和无符号整数类型。
概述
此crate的目标是提供与Rust原生整数类型(如u8、i8、u16、i16等)完全相同的整数类型:几乎所有在Rust的有符号和无符号原生整数上定义的方法都在bnum的有符号和无符号整数上定义。此外,还提供了一些其他有用的方法,大部分灵感来自BigInt和BigUint类型,这些类型来自num_bigint crate。
此crate使用Rust的const generics来允许创建在编译时可以确定的任意大小的整数。无符号整数存储为长度为N的数字数组(原生无符号整数)。这意味着所有bnum整数都可以存储在栈上,因为它们是固定大小的。有符号整数简单地存储为二进制补码形式的无符号整数。
bnum 定义了 4 种无符号整数类型:每种类型使用不同的原始整数类型作为其数字类型。 BUint 使用 u64 作为其数字类型,BUintD32 使用 u32,BUintD16 使用 u16,而 BUintD8 使用 u8。有符号整数类型 BInt、BIntD32、BIntD16 和 BIntD8 分别由这些无符号整数表示。
BUint 和 BInt 由于存储(并且因此操作)给定位数大小的最少数字,所以速度最快。然而,缺点是位数大小必须是 64 的倍数(bitsize = N * 64)。这就是为什么还提供了其他整数类型,因为它们允许位数大小是 32、16 或 8 的倍数。在选择使用哪种类型时,确定 64, 32, 16, 8 中的哪一个是最大除数,并使用相应的类型。例如,如果您想有一个 96 位的无符号整数,32 是这些中 96 的最大除数,所以使用 BUintD32<3>。一个 40 位的有符号整数将是 BIntD8<5>。
为什么是 bnum?
- 默认无依赖:默认情况下,
bnum不依赖于任何其他 crate。可以通过 crate features 启用对rand和serde等crate 的支持。 no-std兼容:如果未启用arbitrary和quickcheck功能,则bnum可以在no_std环境中使用。- 编译时整数解析:在
bnum整数上的from_str_radix和parse_str_radix方法是const,这使得可以在编译时解析来自字符串切片的整数。请注意,这比编译时解析整数文字更强大。这是因为它允许解析从2到36的所有基数(包括2、8、10和16)。此外,要解析的字符串不一定是文字:例如,它可以通过include_str!或env!` 获取。 const评估:在bnum整数上定义的几乎所有方法都是const,这允许复杂的编译时计算。
安装
要安装和使用bnum,只需将以下行添加到您的Cargo.toml文件中的[dependencies]部分
bnum = "0.11.0"
或者,为了启用bnum的各种功能,例如,添加以下行代替
bnum = { version = "0.11.0", features = ["rand"] } # enables the "rand" feature
示例用法
注意:文档中的示例使用特定的类型别名(例如U256、U512或I256、I512)来给出大多数方法的正确使用示例。这些类型并没有什么特殊之处:所有使用这些类型展示的方法都为任何值N的所有无符号/有符号bnum整数实现了。
// As of version 0.6.0, you can parse integers from string slices at compile time with the const methods `from_str_radix` or `parse_str_radix`:
use bnum::types::{U256, I256};
use bnum::errors::ParseIntError;
// `parse_str_radix` returns an integer, and panics if the string fails to parse
const UINT_FROM_DECIMAL_STR: U256 = U256::parse_str_radix("12345678901234567890", 10);
// If you are not sure that the string will successfully parse, you can use `from_str_radix` which returns a `Result`
const RESULT_INT_FROM_HEXA_STR: Result<I256, ParseIntError> = I256::from_str_radix("-1234567890abcdef", 16);
assert_eq!(format!("{}", UINT_FROM_DECIMAL_STR), "12345678901234567890");
assert_eq!(format!("{:x}", RESULT_INT_FROM_HEXA_STR.unwrap().abs()), "1234567890abcdef");
// Calculate the `n`th Fibonacci number, using the type alias `U512`.
use bnum::types::U512; // `U512` is a type alias for a `BUint` which contains 8 `u64` digits
// Calculate the nth Fibonacci number
fn fibonacci(n: usize) -> U512 {
let mut f_n: U512 = U512::ZERO; // or `U512::from(0u8)`
let mut f_n_next: U512 = U512::ONE; // or `U512::from(1u8)`
for _ in 0..n {
let temp = f_n_next;
f_n_next += f_n;
f_n = temp;
}
f_n
}
let n = 100;
let f_n = fibonacci(n);
println!("The {}th Fibonacci number is {}", n, f_n);
// Prints "The 100th Fibonacci number is 354224848179261915075"
assert_eq!(f_n, U512::from_str_radix("354224848179261915075", 10).unwrap());
// Construct an 80-bit signed integer
// Out of [64, 32, 16, 8], 16 is the largest divisor of 80, so use `BIntD16`
use bnum::BIntD16;
type I80 = BIntD16<5>; // 80 / 16 = 5
let neg_one = I80::NEG_ONE; // -1
assert_eq!(neg_one.count_ones(), 80); // signed integers are stored in two's complement so `-1` is represented as `111111...`
功能
模糊测试
arbitrary功能从arbitrary存储库中推导出Arbitrary特质。**注意:目前,此功能无法与no_std一起使用(请参阅https://github.com/rust-fuzz/arbitrary/issues/38)**。
随机数生成
rand功能允许通过rand存储库创建随机bnum整数。
序列化和反序列化
serde功能通过serde和serde_big_array存储库启用bnum整数的序列化和反序列化。
num_traits和num_integer特质实现
numtraits功能包括来自num_traits和num_integer存储库的特质的实现,例如AsPrimitive、Signed、Integer和Roots。
Quickcheck
quickcheck功能启用quickcheck存储库中的Arbitrary特质。**注意:目前,此功能无法与no_std一起使用**。
Zeroize
zeroize功能启用zeroize存储库中的Zeroize特质。
Valuable
valuable功能启用valuable存储库中的Valuable特质。
夜间功能
激活 nightly 功能将启用 from_be_bytes、from_le_bytes、from_ne_bytes、to_be_bytes、to_le_bytes 和 to_ne_bytes 方法,这些方法作用于 bnum 的无符号和有符号整数,并将 unchecked_... 方法标记为 const。但这样做代价是只能编译在 nightly 版本上。这个功能使用的 nightly 特性包括:generic_const_exprs、const_trait_impl 和 const_option_ext。
测试
此软件包使用 quickcheck 软件包以及特定的边缘情况进行测试。将方法输出与原始整数的等效方法输出进行比较,以确保行为相同。
最低支持的 Rust 版本
当前最低支持的 Rust 版本 (MSRV) 为 1.65.0。
文档
如果一个方法没有明确文档,它将链接到原始 Rust 整数上定义的等效方法(因为它们具有相同的功能)。
注意:bnum 目前处于预 1.0.0 阶段。根据 语义版本控制指南,在此阶段,公共 API 可能包含破坏性更改。然而,由于 API 设计尽可能类似于 Rust 原始整数的 API,因此不太可能出现大量的破坏性更改。
已知问题
目前,对于 bnum 整数实现了 From 特性,从所有 Rust 原始整数。然而,这种行为并不完全正确。例如,如果创建了一个 24 位宽的无符号整数(BUintD8<3>),则不应实现 From<u32> 等,而应实现 TryFrom<u32>。为确保正确的行为,可以使用来自 num_traits 软件包的 FromPrimitive 特性,因为这总会返回一个 Option 而不是整数本身。
num_traits::NumCast 特性为 bnum 整数实现了,但如果调用其方法 from,则会故意触发 panic,因为这无法保证正确的转换,因为 NumCast 特性强制执行了约束。因此,不应在 bnum 整数上使用此特性。此实现的唯一目的是允许实现 num_traits::PrimInt 特性。
以前的错误
以前版本中的错误列表可以在 changes/prior-bugs.md 找到。
未来工作
此库旨在提供 Rust 的 3 种内置数字类型的任意精度和固定精度等效项:有符号整数、无符号整数和浮点数。有符号和无符号整数已实现并经过全面测试,并力求与 Rust 的整数接口保持同步。(例如,当在 Rust 原始整数上实现新方法时,此库将努力同步,包括该方法。这包括仅限夜间的功能。)
目前,正在开发任意精度固定大小浮点数,但尚不完整。大多数基本方法,如算术和分类,已实现,但截至目前,尚未实现如 sin、exp、log 等超越浮点数方法。
此外,还将在某个时候开发用于解析数字值的 proc 模块。
许可
bnum 许可证为 MIT 许可证或 Apache 许可证 2.0。
依赖项
~0–500KB