我读了一些十六进制数字然后我想把它们转换成2 ^ 64。不幸的是,由于这个数字不能存储在int中,因此GMP中似乎没有任何功能可以帮助我解决这个问题。
还有另外一种方法可以完全消失吗?
(该程序在C中)
答案 0 :(得分:1)
10是1010
,二进制是1 0 1 0
10是22
,二进制是10 10
10是12
,二进制是001 010
10是A
,二进制是1010
我试图向您展示的模式(以及其他人已经注意到的)是它们都具有相同的二进制表示。换句话说,如果将数字转换为基数256(char
s)并将其写入文件或内存,则可以在基数2 ^ 16(一次读取2个字节)或基数2中读取它。 ^ 32(一次4个字节),或实际上2 ^任何东西。它将是相同的二进制表示(假设你得到你的endians正确)。因此要小心使用big / little endian并将其读作int64_t
。
要清楚,这仅适用于2 ^ n的碱基。基数5中的10是20
,二进制是010 000
;明显不同。但是如果你使用三元组,同样的原则适用于3 ^ n,而在自愿(?)中则适用于5 ^ n。
更新:如何使用它:
有一些功能
void convert(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];
稍微复杂一点,但仍然很容易自动化。
答案 1 :(得分:0)
GMP附带的stdio.h
扩展名适用于大数字,请参阅Formatted Input Functions上的手册。
通常的标准输入可用于标准输入(gmp_scanf
),文件(gmp_fscanf
)或已读入内存的字符串(gmp_sscanf
)。