PDA

View Full Version : base64 encoding



boban
- 7th April 2008, 16:53
Hello,
has anyone the idea, how to do base64 encoding of the short string? I need it to encode the e-mail username and password...

Kamikaze47
- 7th April 2008, 17:08
I would take your input array of bytes and using a simple loop, create an array of bits.

Then using a second loop, read those bits 6 at a time and use a combination of math and a lookup table to generate the output.

The wikipedia article on Base64 has a lot of useful info, including C code for encoding and decoding:

http://en.wikipedia.org/wiki/Base64

Kamikaze47
- 8th April 2008, 21:46
Was bored, so I figured i would give this a shot.

Untested, so try at your own risk :)


STRING_LENGTH CON 24 ; Must be divisable by 3

in_string VAR BYTE[STRING_LENGTH]
in_byte VAR BYTE
in_bit VAR BYTE
b64_string VAR BYTE[STRING_LENGTH*4/3]
b64_byte VAR BYTE
b64_bit VAR BYTE
temp VAR BYTE

in_byte=0 ; Start at byte 0
in_bit=7 ; Most significant bit first

FOR b64_byte=0 TO (STRING_LENGTH*4/3)-1 ; For each base64 byte:
b64_string[b64_byte]=0 ; Clear the byte
FOR b64_bit=5 TO 0 STEP -1 ; For each bit 5 thru 0:
temp=in_string[in_byte] ; Get the current input byte
temp=temp >> in_bit ; Shift to get the current bit as bit 0
temp=temp & 1 ; Clear the other bits
temp=temp << b64_bit ; Shift to the correct output bit position
b64_string[b64_byte]=temp|b64_string[b64_byte] ; Add the bit to the base64 byte
in_bit=in_bit-1 ; Next less significant bit
IF in_bit=255 THEN ; If we past bit 0:
in_bit=7 ; Set to bit 7 of the next byte
in_byte=in_byte+1
ENDIF
NEXT b64_bit
SELECT CASE b64_string[b64_byte] ; Convert to base64 coded ASCII
CASE IS<=25 ; 0-25
b64_string[b64_byte]=b64_string[b64_byte]+65; "A"-"Z"
CASE IS<=51 ; 26-51
b64_string[b64_byte]=b64_string[b64_byte]+71; "a"-"z"
CASE IS<=61 ; 52-61
b64_string[b64_byte]=b64_string[b64_byte]-4 ; "0"-"9"
CASE 62 ; 62
b64_string[b64_byte]=43 ; "+"
CASE 63 ; 63
b64_string[b64_byte]=47 ; "/"
END SELECT
NEXT b64_byte

mister_e
- 8th April 2008, 22:11
Boban, which PIC you plan to use?

Who's interested to participate to a "convenient and ease of use routine" contest ? Just for fun though...

mister_e
- 9th April 2008, 01:16
No one? ;)

i had a 1/2 hour to kill so i did this one. No matter if your string is dividable by three or not, the software will adjust it. I've compare my results with the following online converter tool

http://makcoder.sourceforge.net/demo/base64.php

Everything seems ok. Personnal and deliberate decision from myself to remove the comments... oh i'm a monster :D

You just need to figure out ;)

This assume your PIC have a 256 bytes EEPROM. I used a dusty F877



<font color="#000000"> @ __CONFIG _HS_OSC &amp; _LVP_OFF &amp; _WDT_OFF
<font color="#000080">DEFINE </font>OSC 20

<font color="#000080">DEFINE </font>HSER_RCSTA 90h <font color="#008000">' Enable serial port &amp; continuous receive
</font><font color="#000080">DEFINE </font>HSER_TXSTA 24h <font color="#008000">' Enable transmit, BRGH = 1
</font><font color="#000080">DEFINE </font>HSER_SPBRG 129 <font color="#008000">' 9600 Baud @ 20MHz, 0.16%
</font><font color="#000080">DEFINE </font>HSER_CLROERR 1 <font color="#008000">' Clear overflow automatically

</font>Len <font color="#000080">VAR BYTE
</font>ByteA <font color="#000080">VAR BYTE
</font>buffer <font color="#000080">VAR BYTE</font>[3]
Encoded <font color="#000080">VAR BYTE</font>[4]
EncodedCounter <font color="#000080">VAR BYTE

</font>CounterA <font color="#000080">VAR BYTE
</font>CounterB <font color="#000080">VAR BYTE


</font>String1 <font color="#000080">DATA </font>&quot;Man is distinguished, not only by his reason, but by this singular passion &quot;<font color="#008000">;from other animals, which is a lust of the mind, that by a perseverance of delight in the continued and indefatigable generation of knowledge, exceeds the short vehemence of any carnal pleasure.&quot;
</font>String2 <font color="#000080">DATA </font>0

BASE64Table <font color="#000080">DATA </font>@191, &quot;ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvw xyz0123456789+/=&quot;

Len = String2 - String1

<font color="#000080">IF </font>(Len//3) <font color="#000080">THEN
</font>ByteA=3-(Len//3)
<font color="#000080">FOR </font>CounterA=0 <font color="#000080">TO </font>(ByteA-1)
<font color="#000080">WRITE </font>(Len+CounterA),0
<font color="#000080">NEXT
</font>Len=Len+ByteA
<font color="#000080">ENDIF

HSEROUT </font>[&quot;Len=&quot;,<font color="#000080">DEC </font>Len,13,10,_
&quot;Original string&quot;,13,10]

<font color="#000080">FOR </font>CounterA=0 <font color="#000080">TO </font>(Len-1)
<font color="#000080">READ </font>CounterA,ByteA
<font color="#000080">IF </font>ByteA <font color="#000080">THEN
HSEROUT </font>[ByteA]
<font color="#000080">ENDIF
NEXT

HSEROUT </font>[13,10, &quot;Encoded String&quot;,13,10]
EncodedCounter=0

<font color="#000080">FOR </font>CounterA=0 <font color="#000080">TO </font>(Len-3) <font color="#000080">STEP </font>3
<font color="#000080">READ </font>CounterA, buffer[0]
<font color="#000080">READ </font>(CounterA+1), buffer[1]
<font color="#000080">READ </font>(CounterA+2), buffer[2]
Encoded[0]=buffer[0]&gt;&gt;2
Encoded[1]=((buffer[0]&amp;3) &lt;&lt;4) | (buffer[1]&gt;&gt;4)

<font color="#000080">IF </font>buffer[1] <font color="#000080">THEN
</font>Encoded[2]=((buffer[1]&amp;$0F)&lt;&lt;2) | (buffer[2]&gt;&gt;6)
<font color="#000080">ELSE
</font>Encoded[2]=64
<font color="#000080">ENDIF

IF </font>buffer[2] <font color="#000080">THEN
</font>Encoded[3]=buffer[2] &amp; %00111111
<font color="#000080">ELSE
</font>Encoded[3]=64
<font color="#000080">ENDIF
</font>EncodedCounter=EncodedCounter+4

<font color="#000080">FOR </font>CounterB=0 <font color="#000080">TO </font>3
<font color="#000080">READ </font>(Base64Table+Encoded[CounterB]),ByteA
<font color="#000080">HSEROUT </font>[ByteA]
<font color="#000080">NEXT
NEXT

STOP
END
</font>

There's load of room for improvement. At least it works!

There's still the "convenient" part to do... if really needed and asked.

Kamikaze47
- 9th April 2008, 08:02
Touché

:)

Kamikaze47
- 9th April 2008, 08:38
Personnal and deliberate decision from myself to remove the comments.

Do you mean:


Personal and deliberate decision from myself to be lazy and not write any comments in the first place.

:P

mister_e
- 9th April 2008, 15:02
mmm time saving... maybe true ;)

boban
- 12th August 2008, 09:31
Cus, I am very soory for the too late delay, I have a lot personal stuff to do and didn't had time for the playing.I see, that you have spent a lot of time to do it, it is nice inspiration for me to use your code. Thans a lot - it is both of you!!!