【问题标题】:split a number using OpenSSL's BIGNUM as quickly as possible尽快使用 OpenSSL 的 BIGNUM 拆分一个数字
【发布时间】:2016-01-21 17:54:18
【问题描述】:

我将 OpenSSL 的 BIGNUM 库用于任意精度数。

我需要将一个数字分成两部分。我需要一个数字中的前 n 位 [0, n-1](我的意思是 n 个最低有效位),其余的位 [n, end] 在另一个数字中。

我的代码是这样的

void number_split(BIGNUM * first_n_bits, BIGNUM * the_rest, BIGNUM * number, long n) {
    int i = 0;

    BN_copy(first_n_bits, number);

    int bits = BN_num_bits(first_n_bits);

    while(bits > n) {
        BN_clear_bit(first_n_bits, --bits);
    }

    if(BN_num_bits(number) > n) {
        BN_rshift(the_rest, number, n);
    } else {
        BN_copy(the_rest, zero);
    }
}

我已经确定这个函数是我的应用程序执行时间的最大贡献者之一,所以让它更快一点会对我有很大帮助。

似乎可以改进的部分是while 循环,我一次清除一个最重要的位。我原以为 BIGNIM 会有一个更有效地完成此任务的功能,但我找不到它。

那么,我该怎么做才能加快速度呢?

【问题讨论】:

    标签: c openssl bignum


    【解决方案1】:

    您可以使用BN_mask_bits() 函数,它应该比循环遍历每一位更快。

    // BN_num_bits(num) must be >= n
    void number_split(BIGNUM *low_bits, BIGNUM *high_bits, BIGNUM *num, long n) {
      BN_copy(low_bits, num);
      BN_mask_bits(low_bits, n);
      BN_rshift(high_bits, num, n);
    }
    

    如果BN_num_bits(num) < n 可能,则添加一个检查:

    void number_split(BIGNUM *low_bits, BIGNUM *high_bits, BIGNUM *num, long n) {
      BN_copy(low_bits, num);
      if(BN_num_bits(num) <= n) {
        BN_copy(high_bits, zero);
      } else {
        BN_mask_bits(low_bits, n);
        BN_rshift(high_bits, num, n);
      }
    }
    

    【讨论】:

    • 对您的解决方案的一个小改动,BN_mask_bits 对 num 进行了就地修改,它不会像 BN_rshift 那样将结果放入新结构中。因此,您必须先将num 复制到low_bits,然后将low_bits 屏蔽
    • 谢谢!效果很好!我的应用程序由此获得了 33% 的净加速。
    • @Luke,哦,是的-我已经更新了我的答案,在BN_mask_bits() 之前使用BN_copy()。很高兴听到它有帮助!
    猜你喜欢
    • 1970-01-01
    • 2016-11-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-09-17
    • 1970-01-01
    相关资源
    最近更新 更多