2013-06-06 4 views
2

Je travaille avec la bibliothèque openssl BIGNUM en C++. Le problème que j'ai, c'est que j'ai besoin de calculer le and bits de deux BIGNUM valeurs a et b, mais je ne peux pas comprendre comment faire cela. J'ai cherché sur le web pendant un moment maintenant, mais je ne trouve rien d'utile.Comment effectuer un AND bit à bit de deux BIGNUM?

Répondre

0

Il semble qu'il n'y ait aucune fonction pour le faire directement, par conséquent vous devrez trouver quelque chose basé sur la fonctionnalité qui est là. Quelque chose comme:

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); 
} 

Notez que cela peut être nécessaire de définir manuellement les bits d'ordre supérieur à 0 si la longueur en bits de a est supérieure à b ou vice-versa. Cela devrait suffire pour commencer, cependant.

3

Il n'y a pas de bit et de fonction pour BIGNUM dans OpenSSL. Voici comment je fais au bit-et vous pouvez l'utiliser jusqu'à ce que vous trouviez une solution adéquate.

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); 
} 

La fonction interne au-dessus de bn_and_words est utilisé dans cette fonction:

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; 
} 

Résultat r de a AND b est le premier argument et la valeur de retour de la fonction BN_bitwise_and.

Voici un test:

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); 
} 

Le résultat r imprimé sur stdout est

1214120880214121 

Hope this helps.

+0

Merci beaucoup. C'est calme surprenant que ce n'est pas directement possible dans openssl, mais ça a l'air génial – user2457823

+0

Vous êtes les bienvenus :) – ChiaraHsieh