【问题标题】:How can I save a GMP mpz_t/mpz_class to vector<byte>?如何将 GMP mpz_t/mpz_class 保存到 vector<byte>?
【发布时间】:2014-06-03 13:35:03
【问题描述】:

我需要将mpz_class 类型转换为vector&lt;byte&gt;,反之亦然。
我实现了这两个功能,但是往返转换被破坏了。

typedef unsigned char byte;

std::vector<byte> mpz_to_vector(std::shared_ptr<mpz_class> x) {
    size_t size;
    byte *a = (byte *) mpz_export(NULL, &size, 1, 1, 1, 0,x->get_mpz_t());
    std::vector<byte> p(a,a+size);
    free(a);
    return p;
}

std::shared_ptr<mpz_class>vector_to_mpz(std::vector<byte> d) {
    mpz_class ptr;
    mpz_import(ptr.get_mpz_t(), d.size(), 1, sizeof(mpz_t), 1, 0, (void *) d.data());
    auto tmp = std::shared_ptr<mpz_class>(new mpz_class(ptr));
    return tmp;
}

【问题讨论】:

  • 避免动态分配,尤其是手动分配:为什么size 是指向动态分配的size_t 的指针?此外,无需在mpz_export 中分配临时缓冲区。该手册包含调整输出缓冲区大小的正确算法。
  • 我删除了动态分配的大小。我不确定我是否理解你。你认为问题出在出口还是进口?

标签: c++ gmp


【解决方案1】:

避免动态分配,尤其是手动分配:为什么size 是指向动态分配的size_t 的指针?
您不需要任何临时缓冲区,因此请删除它们。该手册包含用于调整输出缓冲区大小的正确算法。
应用这个,我们得到了这个导出器:

std::vector<byte> mpz_to_vector(const mpz_t x) {
    size_t size = (mpz_sizeinbase (x, 2) + CHAR_BIT-1) / CHAR_BIT;
    std::vector<byte> v(size);
    mpz_export(&v[0], &size, 1, 1, 0, 0, x);
    v.resize(size);
    return v;
}
inline std::vector<byte> mpz_to_vector(std::shared_ptr<mpz_class>& x) {
    return mpz_to_vector(x->get_mpz_t());
}

进口商也遭受不必要的复制。
不过,唯一的错误是向mpz_export提供错误的参数。
纠正这一切给了我们:

std::shared_ptr<mpz_class> vector_to_mpz(const std::vector<byte>& d) {
    auto p = make_shared<mpz_class>();
    mpz_import(p->get_mpz_t(), d.size(), 1, 1, 0, 0, &d[0]);
    return p;
}

顺便说一句:我使用了make_shared,因为这在良好的实现中比手动执行更有效,并且可以实现异常安全。

【讨论】:

  • 非常感谢。你能解释一下导出的算法吗?
  • #bits => #(partial) 大小为 b 位的字的简单转换。请记住,C++ 除法四舍五入为 0。无论如何,这是手册中的简单副本。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-10-16
  • 1970-01-01
  • 2021-11-12
相关资源
最近更新 更多