سؤال

أحاول استخدام وظائف BN_ * في Openssl. على وجه التحديد، لدي التعليمات البرمجية التالية:

#import <openssl/bn.h>
BIGNUM * num = BN_new();
BN_set_word(num, 42);
char * buffer = malloc((BN_num_bytes(num)+1) * sizeof(char));
buffer[BN_num_bytes(num)] = '\0';
int len = BN_bn2bin(num, buffer);
printf("42 in binary is %s\n", buffer);

ومع ذلك، عندما أفعل هذا، لا أحصل على سلسلة من الأزهار والأصفار. بدلا من ذلك يطبع "42 in binary is *". وبعد بقدر ما أستطيع أن أقول، ومن جداً عدد محدود من الأمثلة المتاحة على الويب التي قارنت ذلك، لقد قمت بتنفيذ هذا بشكل صحيح.

أي أفكار لماذا لا تعمل؟

هل كانت مفيدة؟

المحلول

BN_bn2bin لا تنشئ سلسلة قابلة للطباعة - بدلا من ذلك، فإنه يخلق تمثيل ثنائي حقا (أي تسلسل بت). وبشكل أكثر تحديدا، يقوم بإنشاء تمثيل كبير للرقم. منذ 42 يناسب بايت واحد، تحصل على بايت واحد 0x2a، وهو "*" في ASCII.

إذا كنت ترغب في تمثيل 0/1، فأنت بحاجة إلى التكرار فوق جميع البايتات، والقيام بالطباعة بنفسك (على سبيل المثال مع تحويل أو جدول بحث).

نصائح أخرى

إليك بعض الكود الذي يتحول فعليا BN_bn2bin الإخراج في سلسلة قابلة للطباعة تماما مثل إخراج BN_bn2dec و BN_bn2hex. وبعد إنه في مكتبة Nodejs ولكنه مكتوب في C ++ للسرعة. أخذني طوال اليوم وربما ليس مثاليا (لأنني لم أكتب أي رمز C ++ منذ السنة الأولى من UNI). لكنه يمر مجموعة من اختبارات الوحدة حتى أعرف أنها تعمل!

https://github.com/malcolmocean/node-bignum.

if (BN_is_zero(&bignum->bignum_)) {
  to = (char*) OPENSSL_malloc(2*sizeof(char));
  to[0] = '0';
  to[1] = '\0';
} else {
  unsigned char *binary = (unsigned char*) OPENSSL_malloc(BN_num_bytes(&bignum->bignum_)*sizeof(unsigned char));
  int len = BN_bn2bin(&bignum->bignum_, binary);
  to = (char*) OPENSSL_malloc((len*8+2)*sizeof(char));
  int offset = 0;
  if (BN_is_negative(&bignum->bignum_)) {
    to[0] = '-';
    offset--;
  }
  unsigned char x = binary[0];
  while (!(x & 128) && x) {
    x = x << 1;
    offset++;
  }
  for (int i = 0; i < len; i++) {
    unsigned char bits = binary[i];

    int j=7;
    while(bits) {
      if (bits & 1) {
        to[8*i+j-offset] = '1';
      } else {
        to[8*i+j-offset] = '0';
      }
      bits = bits >> 1;
      j--;
    }
    if (i > 0) {
      while (j >= 0) {
        to[8*i+j-offset] = '0';
        j--;
      }
    }
  }
  to[8*len-offset] = '\0';
  OPENSSL_free(binary);
}
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top