【发布时间】:2025-12-01 14:20:05
【问题描述】:
我正在为基于 C++ 的加密方案开发一个 python 包装器,其中密钥和密文是非常大的数字(最多 2048 位)。
在 C++ 中,我使用 Intel BigNumber class 来存储和处理如此大的数字。
由于 Python 本身通过对象支持“看似”无限位的整数,因此我无法通过 Python 将此类变量作为参数传递。
py::class_<BigNumber>(m, "BigNumber")
.def(py::init<unsigned int>())
.def(py::init<int>())
.def(py::init<BigNumber>())
.def(py::init([](py::list data) {
size_t length = data.size();
unsigned int* pData = new unsigned int[length];
for (int i = 0; i < length; i++) {
pData[i] = data[i].cast<unsigned int>();
}
return std::unique_ptr<BigNumber>(new BigNumber(pData, length));
}))
.def(py::init([](py::array_t<unsigned int> data) {
py::buffer_info buffer_info = data.request();
unsigned int* pData = static_cast<unsigned int*>(buffer_info.ptr);
std::vector<ssize_t> shape = buffer_info.shape;
return std::unique_ptr<BigNumber>(new BigNumber(pData, shape[0]));
}))
以上部分允许最多 32 位的单个变量或分解的大整数列表/数组(每个 32 位)
如果我想从 Python 中获取非常大的整数作为输入来填充 BigNumber 类,我应该如何定义一个返回为 Python 可理解的大整数对象的 def_property_readonly() 函数?
Edit1:将大整数从 Python 传递到 C++
在BigNumber(const char* s)构造函数的帮助下,可以通过:
.def(py::init([](py::object obj){
std::string s_obj = py::str(obj);
return std::unique_ptr<BigNumber>(new BigNumber(&s_obj[0]));
}))
弄清楚如何进行反向操作,可能是 std::string 到 py::object 和 py::cast?
【问题讨论】:
-
我是个黑客。当我需要在程序和语言之间移动数据时,我会将大数字转换为字符串。
-
C/C++-- 没有这样的语言。它是 C 或 C++。 -
请注意,十进制和二进制之间的转换实际上具有非常糟糕的渐近运行时间,因此如果您要通过字符串表示,至少尝试使用十六进制或二进制或其他东西而不是十进制。
-
你是我喜欢的黑客。使用字符串很简单,而且该死的几乎是万无一失的。这是一个很好的起点(如果没有性能问题,请留下来)。小建议:把
return std::unique_ptr<BigNumber>(new BigNumber(&s_obj[0]));换成return std::make_unique(s_obj.c_str());。 There's less room for error. -
如果您在 C 级别更改为使用
GMP表示数字(很确定有 C++ 包装器),可能有一种直接的方法来创建gmpy2.xmpz(可变的)或 @ 987654336@(不可变,这意味着您肯定必须复制 - 但是,无论如何您可能都必须复制)。即使您不这样做,您也可以检查 it 如何进行intmpz转换...
标签: python c++ pybind11 bignum