0

我读了一些十六进制数字,然后我想将它们转换为基数 2^64。不幸的是,由于这个数字不能存储在一个 int 中,似乎 GMP 中没有可以帮助我解决这个问题的函数。

还有另一种我完全想念的方法吗?

(程序是C语言)

4

2 回答 2

1

以 2^1 为基数的 10 是1010二进制的1 0 1 0

以 2^2 为基数的 10 是22二进制的10 10

以 2^3 为基数的 10 是12二进制的001 010

以 2^4 为基数的 10 是A二进制的1010

我试图向您展示的模式(以及其他人已经注意到的)是它们都具有相同的二进制表示。换句话说,如果您将您的数字转换为基数 256 ( chars) 并将其写入文件或内存,您可以在基数 2^16(一次读取 2 个字节)或基数 2^32(4 个字节)中读取它一次),或者实际上是 2^anything。它将是相同的二进制表示(假设您的字节序正确)。所以要小心使用大端与小端并读为int64_t.

需要明确的是,这仅适用于 2^n 的碱基。以 5 为底的 10 是20二进制中的010 000; 明显不同。但是如果你使用三进制,同样的原理也适用于 3^n,而在五进制 (?) 中它也适用于 5^n。

更新:你如何使用它:

有一些功能

无效转换(char *myBase16String,uint8_t *outputBase256);

我们假设采用以 16 为基数编码的字符串并生成一个无符号字符数组,其中每个字符都是以 256 为基数的一个单元,我们这样做:

uint8_t base2_8[8];
convert( "0123456789ABCDEF", base2_8 );
uint64_t base2_64[2];
base2_64[0] = (base2_8[0] << 24) | (base2_8[1] << 16) | (base2_8[2] << 8) | base2_8[3];
base2_64[1] = (base2_8[4] << 24) | (base2_8[5] << 16) | (base2_8[6] << 8) | base2_8[7];
// etc. You can do this in a loop, but make sure you know how long it is.

假设您的输入不是一个很好的 4 个字节的倍数:

uint8_t base2_8[6];
convert( "0123456789AB", base2_8 );
uint64_t base2_64[2];
base2_64[0] =                                           (base2_8[0] << 8) | base2_8[1];
base2_64[1] = (base2_8[2] << 24) | (base2_8[3] << 16) | (base2_8[4] << 8) | base2_8[5];

稍微复杂一些,但仍然很容易自动化。

于 2013-03-16T23:09:46.980 回答
0

GMP 附带了stdio.h适用于大量数字的扩展,请参阅格式化输入函数手册。

gmp_scanf标准输入 ( )、文件 ( gmp_fscanf) 或您已经读入内存 ( ) 的字符串有一些常用的风格gmp_sscanf

于 2015-05-19T05:23:38.753 回答