Pergunta

I read in some hex numbers and I then would like to convert them to base 2^64. Unfortunately as this number cannot be stored in an int, it seems there is no function in GMP that can help me solve this problem.

Is there another way to do this that I am missing completely?

(The program is in C)

Foi útil?

Solução

10 in base 2^1 is 1010 which in binary is 1 0 1 0

10 in base 2^2 is 22 which in binary is 10 10

10 in base 2^3 is 12 which in binary is 001 010

10 in base 2^4 is A which in binary is 1010

The pattern I'm trying to show you (and that others have noted) is that they all have the same binary representation. In other words, if you convert your number to base 256 (chars) and write it to a file or memory, you can read it in base 2^16 (reading 2 bytes at a time), or base 2^32 (4 bytes at a time), or in fact 2^anything. It will be the same binary representation (assuming you get your endians correct). So be careful with big vs little endian and read as int64_t.

To be clear, this only applies to bases which are 2^n. 10 in base 5 is 20 which in binary is 010 000; obviously different. But if you use trinary, the same principle applies to 3^n, and in pentary (?) it would apply to 5^n.

Update: How you could use this:

With some function

void convert( char *myBase16String, uint8_t *outputBase256 );

which we suppose takes a string encoded in base 16 and produces an array of unsigned chars, where each char is a unit in base 256, we do this:

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.

Suppose your input wasn't a nice multiple-of-4 bytes:

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];

Slightly more complex, but still pretty easy to automate.

Outras dicas

GMP comes with an extension of stdio.h that works on large numbers, see the manual on Formatted Input Functions.

There are the usual flavors that work on either standard input (gmp_scanf), files (gmp_fscanf) or strings you have already read into memory (gmp_sscanf).

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top