如何对两个大整数进行位与运算

How do I perform a bitwise AND of two BIGNUMs?

本文关键字:整数 运算 位与 两个      更新时间:2023-10-16

我正在使用c++中的openssl BIGNUM库。

我的问题是,我需要计算两个BIGNUM值a和b的位and,但我不知道如何做到这一点。我在网上搜了一会儿,但是找不到任何有用的东西。

在OpenSSL中没有bitwise和BIGNUM函数。以下是我按位操作的方法,您可以使用它,直到找到合适的解决方案。

BN_ULONG bn_and_words(BN_ULONG *r, const BN_ULONG *a, const BN_ULONG *b, int n)
{
    BN_ULONG l,t;
    if (n <= 0) return((BN_ULONG)0);
    while(n)
    {
        t=a[0];
        l=(t&b[0]);
        l=(t&b[0])&BN_MASK2;
        r[0]=l;
        a++; b++; r++; n--;
    }
    return((BN_ULONG)*r);
}

上述内部函数bn_and_words在此函数中使用:

int BN_bitwise_and(BIGNUM *r, const BIGNUM *a, const BIGNUM *b)
{
    int max,min,dif;
    BN_ULONG *ap,*bp,*rp;
    const BIGNUM *tmp;
    bn_check_top(a);
    bn_check_top(b);
    if (a->used< b->used)
        { tmp=a; a=b; b=tmp; }
    max = a->used;
    min = b->used;
    dif = max - min;
    if (bn_wexpand(r,max+1) == NULL)
        return 0;
    r->used=max;
    ap=a->d;
    bp=b->d;
    rp=r->d;
    bn_and_words(rp,ap,bp,min);
    rp+=min;
    ap+=min;
    bp+=min;
    while (dif)
    {
        *(rp++) = *(ap++);
        dif--;
    }
    r->neg = 0;
    bn_check_top(r);
    return 1;
}

结果a AND br是第一个参数,也是函数BN_bitwise_and的返回值。

下面是一个测试:

int test_and()
{
    BIGNUM *a,*b,*r;
    a=BN_new();
    b=BN_new();
    r=BN_new();
    if (!BN_hex2bn(&a, "1234567890ABCDEF")) return -1;
    if (!BN_hex2bn(&b, "FEDCBA0987654321")) return -1;
    BN_bitwise_and(r,a,b);
    BN_print_fp(stdout, r);
    BN_free(a);
    BN_free(b);
    BN_free(r);
}

在stdout上打印的r结果是

1214120880214121

看起来没有直接执行此操作的函数,因此您必须根据现有的功能提出一些东西。比如:

BIGNUM *a, *b, *result;
unsigned current = 0;
//Creation of a, b, result
while(!BN_zero(a) && !BN_zero(b)) {
    if(BN_is_bit_set(a, current) && BN_is_bit_set(b, current)) {
        BN_set_bit(result, current);
    } else {
        BN_clear_bit(result, current);
    }
    ++current;
    BN_rshift1(a, a);
    BN_rshift1(b, b);
}

注意,如果a的位长大于b,则可能需要手动将高阶位设置为0,反之亦然。然而,这应该足以让你开始。