我编写了一个使用IPv6地址的程序,我需要将四个整数数组转换为代表IPv6地址数的十进制字符串的代码[1]。现在我遇到了需要做反转的情况:转换可能很大的数字(不适合uint32_t
或uint64_t
,所以atol()
或strtol()
在这里无能为力)表示为四个整数或byte
(uint8_t
)数组的单个字符串(我将[1]中的函数从4-int转换为变量uint8_t)。
有没有办法做到这一点?
[1] How to convert a 128-bit integer to a decimal ascii string in C?
感谢。这是我在这里的第一个问题,如果有的话,对不好的英语感到抱歉。
答案 0 :(得分:0)
建议使用库时出现这种情况。
使用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并在gcc命令行参数上添加-lgmp -std = c99。
在Ubuntu上,您可以使用以下命令安装gmp:
sudo apt-get install libgmp-dev
编译示例,gmp.c:
gcc gmp.c -o gmp -lgmp -std=c99
此代码可以为您的转化提供良好的开端。您也可以将i初始化为固定的128位数字(使用GMP的初始化函数),以防您的大号以零开头。