Как преобразовать десятичную строку ASCII в целочисленный массив в C?

Я написал программу, которая работает с адресами IPv6, и мне нужен был код, который преобразует массив из четырех целых чисел в десятичную строку, представляющую количество адресов IPv6 [1]. Теперь я столкнулся с ситуацией, когда мне нужно сделать обратное: преобразовать, возможно, большое число (которое не вписывается в uint32_t или же uint64_t, так atol() или же strtol() беспомощны здесь) представлены в виде одной строки до четырех целого числа или byte (uint8_t) массив (я преобразовал функцию из [1] из 4-int в variable-uint8_t).

Есть ли способ сделать это?

[1] Как преобразовать 128-битное целое в десятичную строку ascii в C?

Благодарю. Это мой первый вопрос, так что извините за плохой английский, если есть.

1 ответ

Это такая ситуация, когда рекомендуется использовать библиотеку.

Используя GMP, вы можете сделать следующие преобразования (gmp.c):

#include <stdio.h>
#include <stdlib.h>
#include <gmp.h>

int main(int argc, char *argv)
{
  // From string
  char *s ="199999999999999999999999999999999999999";
  mpz_t i;
  // To big number, using GMP
  // 10 here means base 10.
  mpz_init_set_str(i, s, 10);
  // Just to test if s is 128 bits long
  printf("%s can be represented with %d digits in base 2\n",s, mpz_sizeinbase(i, 2));
  // Then you can print it in hex
  gmp_printf("%#32ZX\n", i);
  // Or convert it back to int[4]
  unsigned int a[4];
  mpz_export(&a, NULL, 1, 4, 0, 0, i);
  for(int x=0;x<4;x++)
      printf("%X\n", a[x]); 
  mpz_clear(i);
  return 0;
} 

Выход:

199999999999999999999999999999999999999 can be represented with 128 digits in base 2
0X96769950B50D88F41314447FFFFFFFFF
96769950
B50D88F4
1314447F
FFFFFFFF

Я тестировал этот код в 32-битной системе Linux. Обратите внимание на разные размеры int и endianess на разных платформах. Вы, вероятно, хотите получить результат с прямым порядком байтов, если это так, просто измените mz_export на:

mpz_export(&a, NULL, 1, 4, 1, 0, i);

Чтобы скомпилировать пример, не забудьте установить gmp и добавить -lgmp -std=c99 к параметрам командной строки gcc.

В Ubuntu вы можете установить gmp с:

sudo apt-get install libgmp-dev

И скомпилируйте пример, gmp.c:

gcc gmp.c -o gmp -lgmp -std=c99

Этот код может стать хорошим началом ваших конверсий. Вы также можете инициализировать i как фиксированное 128-битное число (используя функции инициализации GMP), на случай, если ваше большое число начинается с нуля.

Другие вопросы по тегам