realjr
asked on
How do i convert a hex to base64? any sample ANSI C code?
I have a to decode a data to base64 string. I have the hex value of each character of a base64 string.
my limited knowledge is through this:
http://en.wikipedia.org/wiki/Base64
where you can convert a hex to decimal and then to base64 string base on the logic.
are there any simple and efficient ANSI C code available (without linking to other base64.h codes)
thanks!
my limited knowledge is through this:
http://en.wikipedia.org/wiki/Base64
where you can convert a hex to decimal and then to base64 string base on the logic.
are there any simple and efficient ANSI C code available (without linking to other base64.h codes)
thanks!
ASKER
great! thanks, do you have sample ANSI C code (even just the logic part)
ASKER
any sample code for 500 points?
thanks!
thanks!
The wiki you mentioned contains a link to this ANSI C implementation :
http://base64.sourceforge.net/b64.c
Would that suit your needs ? If not, why not ?
http://base64.sourceforge.net/b64.c
Would that suit your needs ? If not, why not ?
interesting question.....
I suddenly had to think back to this question :
https://www.experts-exchange.com/questions/21988706/How-fast-is-your-C-C-Base64-Encoder.html
That was a fun challenge :)
https://www.experts-exchange.com/questions/21988706/How-fast-is-your-C-C-Base64-Encoder.html
That was a fun challenge :)
The following data strings will simplify your algorithm:
BIN = 00000001001000110100010101 1001111000 1001101010 1111001101 11101111
HEX = 0123456789ABCDEF
B64 = ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghij klmnopqrst uvwxyz0123 456789+/
Use the BIN string to initialise an array of nybbles which will be indexed by their equivalent HEX value as in the following:
h[0] = 0000
h[1] = 0001
:
h[9] = 1001
h[A] = 1010
:
h[F] = 1111
So the array h[ ] will be indexed by the enumerated types 0~9, A~F.
Therefore, if you were to input the value '5FA' in hex, then a loop could take each character in turn using something similar to the MID$() function and produce the following results:
h[5] = 0101
h[F] = 1111
h[A] = 1010
During each iteration of the loop, you could append these nybbles to a string as in the following:
binary$ = h[5] + h[F] + h[A]
This would produce the following:
binary$ = 010111111010
The code for this might look something like the following:
LET hex$ = 5FA
FOR i = 0 TO LEN(hex$ - 1) STEP 1
LET binary$ = binary$ + h[MID$(hex$, i, 1))]
NEXT i
The next process involves two stages: converting 6-bit parts to decimal and then using this decimal value to index the B64 string above to return the equivalent base-64 character.
Again, using something similar to the MID$ function, loop through the binary$ string in steps of 6 thereby selecting 6 binary bits at a time and convert them their decimal value. The following will step through the binary$ string:
FOR i = 0 TO LEN(binary$ - 1) STEP 6
LET 6bits = MID$(binary$, i, 6)
:
NEXT i
Before doing this, it may be necessary to pad the binary$ string with leading zeros so that it's length is a multiple of 6. Doing so, you would then need to check whether the first 6 bits are all zero and if so, chop them off.
Inside the FOR loop, you would need to convert the 6-bit binary value to decimal as in the following:
LET decimal = 0
LET multiplyer = 1
FOR i = 5 TO 0 STEP -1
IF MID$(6bit$, i, 1) = 1 THEN LET decimal = decimal + multiplyer
LET muliplyer = multiplyer x 2
NEXT i
At this stage, you will have a decimal value which can now be used to index the B64 string above, as in:
LET base64$ = B64[decimal]
For each iteration of the first FOR loop, the value returned by B64[decimal] is appended to the base64$ string using the following:
LET base64$ = base64$ = B64[decimal]
And there you have it.
I have used a pseudo-code approach in my explanation which I hope makes sense to you.
BIN = 00000001001000110100010101
HEX = 0123456789ABCDEF
B64 = ABCDEFGHIJKLMNOPQRSTUVWXYZ
Use the BIN string to initialise an array of nybbles which will be indexed by their equivalent HEX value as in the following:
h[0] = 0000
h[1] = 0001
:
h[9] = 1001
h[A] = 1010
:
h[F] = 1111
So the array h[ ] will be indexed by the enumerated types 0~9, A~F.
Therefore, if you were to input the value '5FA' in hex, then a loop could take each character in turn using something similar to the MID$() function and produce the following results:
h[5] = 0101
h[F] = 1111
h[A] = 1010
During each iteration of the loop, you could append these nybbles to a string as in the following:
binary$ = h[5] + h[F] + h[A]
This would produce the following:
binary$ = 010111111010
The code for this might look something like the following:
LET hex$ = 5FA
FOR i = 0 TO LEN(hex$ - 1) STEP 1
LET binary$ = binary$ + h[MID$(hex$, i, 1))]
NEXT i
The next process involves two stages: converting 6-bit parts to decimal and then using this decimal value to index the B64 string above to return the equivalent base-64 character.
Again, using something similar to the MID$ function, loop through the binary$ string in steps of 6 thereby selecting 6 binary bits at a time and convert them their decimal value. The following will step through the binary$ string:
FOR i = 0 TO LEN(binary$ - 1) STEP 6
LET 6bits = MID$(binary$, i, 6)
:
NEXT i
Before doing this, it may be necessary to pad the binary$ string with leading zeros so that it's length is a multiple of 6. Doing so, you would then need to check whether the first 6 bits are all zero and if so, chop them off.
Inside the FOR loop, you would need to convert the 6-bit binary value to decimal as in the following:
LET decimal = 0
LET multiplyer = 1
FOR i = 5 TO 0 STEP -1
IF MID$(6bit$, i, 1) = 1 THEN LET decimal = decimal + multiplyer
LET muliplyer = multiplyer x 2
NEXT i
At this stage, you will have a decimal value which can now be used to index the B64 string above, as in:
LET base64$ = B64[decimal]
For each iteration of the first FOR loop, the value returned by B64[decimal] is appended to the base64$ string using the following:
LET base64$ = base64$ = B64[decimal]
And there you have it.
I have used a pseudo-code approach in my explanation which I hope makes sense to you.
>> Before doing this, it may be necessary to pad the binary$ string with leading zeros so that it's length is a multiple of 6.
A Base64 encoding uses '=' characters at the end for padding it to a multiple of 3 characters. You don't have to add any further padding ... Just process the data 6 bits at a time (or multiples of 6 bits, depending on your approach).
An "easy" approach is to process the Base64 data 4 characters (24 bits) at a time, which corresponds to 3 bytes of binary data. And vice versa.
There are lookup table approaches of all kinds, platform specific optimizations, etc.
Base64 can be explained quite simply like this :
encoding : Take binary data, and split it up in blocks of 6 bits. Each such block is mapped to a character in the Base64 alphabet (A-Z, a-z, 0-9, '+' and '/'), which is pushed on the output stream.
decoding : Take each character, and transform it to the original block of 6 bits it corresponds to by using the Base64 alphabet, and push those 6 bits on the output stream.
That's it.
A Base64 encoding uses '=' characters at the end for padding it to a multiple of 3 characters. You don't have to add any further padding ... Just process the data 6 bits at a time (or multiples of 6 bits, depending on your approach).
An "easy" approach is to process the Base64 data 4 characters (24 bits) at a time, which corresponds to 3 bytes of binary data. And vice versa.
There are lookup table approaches of all kinds, platform specific optimizations, etc.
Base64 can be explained quite simply like this :
encoding : Take binary data, and split it up in blocks of 6 bits. Each such block is mapped to a character in the Base64 alphabet (A-Z, a-z, 0-9, '+' and '/'), which is pushed on the output stream.
decoding : Take each character, and transform it to the original block of 6 bits it corresponds to by using the Base64 alphabet, and push those 6 bits on the output stream.
That's it.
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
>> and that padding with '=' is the usual approach.
It's THE approach defined by Base64 ;)
If you want speed, consider reading through the link I posted earlier ... heh :)
It's THE approach defined by Base64 ;)
If you want speed, consider reading through the link I posted earlier ... heh :)
Infinty08
Interesting thread - pity I missed that one at the time.
Interesting thread - pity I missed that one at the time.
Therefore it is more efficient to avoid any decimal intermediate.
Three hex digits produce 2 base64 cracters.
If these three hex digits correspond to numerical values x,y,z, then
the first base64 character corresponds to (x<<2) + (y>>2) and the second to ((y & 3)<< 4) + z.