Comparison between spear and shield-a wonderful base64 encoding [a series of contradictions is quite good]

Source: Internet
Author: User

Http://www.luocong.com/articles/show_article.asp? Article_id = 17

 

Download the example Program (6.93 KB) in this section)

You should be a senior online reader, and the younger brother is brave enough to ask, when surfing the internet, in addition to soaking the MM, bumping the Forum, throwing bricks ...... In addition, what activities are most carried out? By the way, you must say: It's sending and receiving emails! (Who dare say they have confiscated/sent an email? Pulled out and shot !!)

There is a security issue when sending/receiving e-mail-Imagine that you spent a whole day writing a love letter to the department, he was intercepted by Michael Zhang from the dormitory next door during the sending process (is he a hacker ??), What's worse, he's your rival ...... Day, the consequences are unimaginable !! Therefore, we must have a relatively reliable encryption method to convert the plaintext of an email. At least we need something that cannot be seen at a Glance by others, the encoding/decoding speed is also fast enough. (Now, you can imagine another story. Michael's guy intercepted your love letter, but he saw it: "Why? How is it messy? Spam !!" -- In this way, you will not be able to escape the difficulties ?!)

Base64 is the encryption method generated in this context. It features: 1. The speed is very fast. 2. You can convert string a to string B. If you look at string B, you cannot guess the content of string. Believe it? Let's take a look at the following string:

Xoo6w6osu7btrbniwdna z8letctnzbfxzoy12koh

What is it? Have you guessed it? In fact, it is the following text produced by base64 encoding:

Hello! Welcome to the colorful world of Lao Luo!

The introduction is complete. Let's start to explore things.

Base64 is one of the most common encoding methods used to transmit 8-bit code on the network. For details, refer to rfc2045 ~ Rfc2049, which has the mime detailed specification.

Base64 requires that each three 8-bit bytes be converted into four 6-bit bytes (3*8 = 4*6 = 24), and then 6-bit bytes be added with two more high 0 values, it consists of four 8-bit bytes. That is to say, the converted string is theoretically 1/3 longer than the original one.

Will it be too abstract? Not afraid. Let's look at an example:

Before Conversion Aaaaaabb Ccccdddd Eeffffff  
After conversion 00 aaaaaa 00 bbcccc 00 ddddee 00 ffffff

Should it be clear? The above three bytes are the original text, and the following four bytes are base64 encoded after conversion, and the first two are both 0.

After conversion, we use a code table to obtain the desired string (that is, the final base64 encoding). This table is as follows: (from rfc2045)

Table 1: The base64 alphabet

Value encoding value Encoding
0 A 17 R 34 I 51 Z
1 B 18 S 35 J 52 0
2 C 19 t 36 K 53 1
3 D 20 u 37 L 54 2
4 E 21 V 38 m 55 3
5 F 22 W 39 n 56 4
6g 23x40 o 57 5
7 H 24 y 41 P 58 6
8 I 25 Z 42 Q 59 7
9 J 26 A 43 R 60 8
10 K 27 B 44 s 61 9
11 l 28 C 45 t 62 +
12 m 29 D 46 U 63/
13 N 30 E 47 v
14 O 31 F 48 W (PAD) =
15 p 32G 49 x
16 Q 33 H 50 y

Let's take a look at the actual example to help you better understand it!

Before Conversion 10101101 10111010 01110110  
After conversion 00101011 00011011 00101001 00110110
Decimal 43 27 41 54
Values in the corresponding code table R B P 2

Therefore, the base64 value of the preceding 24-bit encoding is rbp2.
Similarly, the original code is obtained by reorganizing the binary join of rbq2 to get three 8-bit values.
(Decoding is only the inverse process of encoding. I will not talk about it here. In addition, there are still many RFC related to mime. If you need details, please search for it yourself .)

The coding process is similar to that of programming:

The first character shifts two places to the right to obtain the location of the base64 table of the first target character. Based on this value, the corresponding character on the table is the first target character.
Then, move the first character four places to the left and the second character four places to the right to obtain the second target character.
Then, remove the second character from the left to the second and the third character to the right to get the third target character.
Finally, take the right 6 digits of the third character to obtain the fourth target character.

After each of the preceding steps, perform the and operation on the result and 0x3f to get the encoded characters.

(Thanks to Athena for pointing out some of the mistakes described above! ^_^)

So easy! That's all !!!

But wait ...... If you are smart, you may ask that the number of bytes in the original text should be a multiple of 3. What if this condition cannot be met?

The solution is as follows: the bytes in the original text can be supplemented with 0, and the base64 encoding is replaced with the = number during conversion. This is why some base64 encoding ends with one or two equal signs, but the equal signs can only be two at most. Because:

Remainder = number of original bytes mod 3

Therefore, the remainder can only be one of the three numbers 0, 1, and 2 in any case. If the remainder is 0, it indicates that the number of original bytes is exactly a multiple of 3 (ideally ). If it is 1, in order to make base64 encoding a multiple of 4, we need to add two equal signs. Similarly, if it is 2, we need to add one equal sign.

At this point, should everyone be clear? If you still have any questions, go back and take a closer look. It is not hard to understand.

The following is a program that demonstrates base64 encoding/decoding, hoping to be useful to you. At the same time, I hope you can help me improve it and use it for more purposes. Don't forget to let me know! (I am too busy now)

DLL source code: base64dll. ASM

; **************************************** *******
Program name: demonstrate base64 encoding/decoding principles
; Author: Luo Cong
; Date: 2002-9-14
Source: http://laoluoc.yeah.net (laoluo's colorful world)
; Note: If you want to reprint it, please keep the program complete and note:
; Reprinted from "Luo's colorful world" (http://laoluoc.yeah.net)
; **************************************** *******

.386
.Model flat,Stdcall
Option Casemap: None

Include/masm32/include/Windows. inc
Include/masm32/include/kernel32.inc
Include/masm32/include/user32.inc
Includelib/masm32/lib/kernel32.lib
Includelib/masm32/lib/user32.lib

Dllentry proto: hinstance,: DWORD,: DWORD
Base64encode proto: DWORD,: DWORD
Base64decode proto: DWORD,: DWORD

.Data
; Base64-> ASCII mapping table
Base64_alphabet DB "abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz0123456789 +/="

; Ascii-> base64 mapping table
Base64table dB 43 DUP (255)
DB 62,255,255,255,63,52,53,54,55,56,57,58,59,60,61,255
DB 255,255,0,255,255,255,0,1,2,3,4,5,6,7,8,9,10,11,12,13
DB 14,15,16,17,18,19,20,21,22,23,24,25,255,255,255,255
DB 255,255,26,27,28,29,30,31,32,33,34,35,36,37,38
DB 39,40,41,42,43,44,45,46,47,48,49,50,51
DB 132 DUP (255)

.Code
Dllentry proc hinst: hinstance,Reason: DWORD,Reserved1: DWORD
MoV eax,True
RET
Dllentry endp


; **************************************** ******************
Function: base64 encoding
; Parameters:
; Source = input string
; Destination = returned Encoding
; **************************************** ******************
Base64encode proc uses ebx edi esi Source: DWORD,Destination: DWORD
Local sourcelen: DWORD

Invoke lstrlen,Source
MoV sourcelen,Eax

MoV ESI,Source
MoV EDI,Destination
@ Base64loop:
XOR eax,Eax
.If sourcelen = 1
Lodsb; source PTR + 1
MoV ECx,2; bytes to output = 2
MoV edX,03d3dh; padding = 2 byte
Dec sourcelen; Length-1
.Elseif sourcelen = 2
Lodsw; source PTR + 2
MoV ECx,3; bytes to output = 3
MoV edX,03dh; padding = 1 byte
Sub sourcelen,2; Length-2
.Else
Lodsd
MoV ECx,4; bytes to output = 4
XOR edX,EdX; padding = 0 byte
Dec ESI; source PTR + 3 (+ 4-1)
Sub sourcelen,3; Length-3
.Endif

Xchg al,Ah; flip eax completely
Rol eax,16; can this be done faster
Xchg al,Ah

@@:
Push eax
And eax,0fc000000h; get the last 6 high bits
Rol eax,6; rotate them into Al
MoV al,Byte PTR [offset base64_alphabet + eax]; get encode character
Stosb; write to destination
Pop eax
SHL eax,6; shift left 6 bits
Dec ECx
Jnz @ B; Loop

CMP sourcelen,0
Jnz @ base64loop; Main Loop

MoV eax,EdX; add padding and null terminate
Stosd

RET
Base64encode endp


; **************************************** ******************
; Function: base64 Decoding
; Parameters:
; Source = input Encoding
; Destination = returned string
; **************************************** ******************
Base64decode proc uses ebx edi esi Source: DWORD,Destination: DWORD
Local sourcelen: DWORD

Invoke lstrlen,Source
MoV sourcelen,Eax

MoV ESI,Source; ESI <-Source
MoV EDI,Destination; EDI <-destination
MoV ECx,Sourcelen
SHR ECx,2
ClD

; ------------- [Decoding part] ---------------

@ Outer_loop:
Push ECx
MoV ECx,4
XOR EBX,EBX
Lodsd
@ Inner_loop:
Push eax
And eax,0ffh
MoV al,Byte PTR [offset base64table + eax]
CMP al,255
Je @ invalid_char
SHL EBX,6
Or BL,Al
Pop eax
SHR eax,8
Dec ECx
Jnz @ inner_loop
MoV eax,EBX
SHL eax,8
Xchg ah,Al
Ror eax,16
Xchg ah,Al
Stosd
Dec EDI
Pop ECx
Dec ECx
Jnz @ outer_loop
XOR eax,Eax
JMP @ decode_done

;-------------------------------------------

@ Invalid_char:
MoV eax,-1
@ Decode_done:
RET
Base64decode endp


End dllentry
; *****************Over ******************* *
; By LC

Test procedure: base64.asm

; **************************************** *******
Program name: demonstrate base64 encoding/decoding principles
; Author: Luo Cong
; Date: 2002-9-14
Source: http://laoluoc.yeah.net (laoluo's colorful world)
; Note: If you want to reprint it, please keep the program complete and note:
; Reprinted from "Luo's colorful world" (http://laoluoc.yeah.net)
; **************************************** *******

.386
.Model flat,Stdcall
Option Casemap: None

Include/masm32/include/Windows. inc
Include/masm32/include/kernel32.inc
Include/masm32/include/user32.inc
Include base64dll. inc
Includelib/masm32/lib/kernel32.lib
Includelib/masm32/lib/user32.lib
Includelib base64dll. Lib

Wndproc proto: DWORD,: DWORD,: DWORD,: DWORD

.Const
Idc_button_encode equ 3000
Idc_button_decode equ 3001
Idc_edit_input equ 3002
Maxsize equ 260

.Data
Szdlgname DB "lc_dialog",0
Szcaption DB "base64 demo by LC",0
Szbuffer dB 255 DUP (0)
Sztext dB 340 DUP (0)
Szmsg dB 450 DUP (0)
The base64 encoding of sztemplate_encode DB "string" "% s" "is :",13,10,13,10,"% S",0
Sztemplate_decode DB "encoding" "% s" the base64 restored string is :",13,10,13,10,"% S",0

.Code
Main:
Invoke getmodulehandle,Null
Invoke dialogboxparam,Eax,Offset szdlgname,0,Wndproc,0
Invoke exitprocess,Eax

Wndproc proc uses EDI hwnd: hwnd,Umsg: uint,Wparam: wparam,Lparam: lparam
Local hedit: hwnd

.If umsg = wm_close
Invoke enddialog,Hwnd,0

.Elseif umsg = wm_command
MoV eax,Wparam
MoV edX,Eax
SHR edX,16
Movzx eax,Ax
.If edX = bn_clicked
.If eax = idcancel
Invoke enddialog,Hwnd,Null

.Elseif eax = idc_button_encode | eax = idok
; Get the user input string:
Invoke getdlgitemtext,Hwnd,Idc_edit_input,ADDR szbuffer,255

; Ascii-> base64 conversion:
Invoke base64encode,ADDR szbuffer,ADDR sztext

; Format the output:
Invoke wsprintf,ADDR szmsg,ADDR sztemplate_encode,ADDR szbuffer,ADDR sztext

; Display result:
Invoke MessageBox,Hwnd,ADDR szmsg,ADDR szcaption,Mb_ OK

.Elseif eax = idc_button_decode
; Get the user input string:
Invoke getdlgitemtext,Hwnd,Idc_edit_input,ADDR szbuffer,255

; For base64-> ASCII conversion:
Invoke base64decode,ADDR szbuffer,ADDR sztext

; Format the output:
Invoke wsprintf,ADDR szmsg,ADDR sztemplate_decode,ADDR szbuffer,ADDR sztext

; Display result:
Invoke MessageBox,Hwnd,ADDR szmsg,ADDR szcaption,Mb_ OK
.Endif

; Select all the content in edit:
Invoke getdlgitem,Hwnd,Idc_edit_input
Invoke sendmessage,Eax,Em_setsel,0,-1

.Endif
.Else
MoV eax,False
RET
.Endif
MoV eax,True
RET
Wndproc endp

End main
; *****************Over ******************* *
; By LC

Resource file of the test program: base64.rc

# Include "resource. H"

# Define idc_button_encode 3000
# Define idc_button_decode 3001
# Define idc_edit_input 3002
# Define idc_static-1

Lc_dialog dialogex 10, 10,195, 60
Style ds_setfont | ds_center | ws_minimizebox | ws_visible | ws_caption |
Ws_sysmenu
Caption "base64 demo by LC"
Font 9, "", 0, 0, 0x0
Begin
Ltext "enter a string:", idc_static, 11, 7,130, 10
Edittext idc_edit_input, 11, 20,173, 12, es_autohscroll
Defpushbutton "encoding (& E)", idc_button_encode, 38, 39, 52, 15
Pushbutton "decoding (& D)", idc_button_decode, 104, 39, 52, 15
End

If you find a bug, please let me know and discuss it with me! Lcother@163.net

Finally, I will leave you with a small exercise. Do you know the original text of this string of base64 encoding? :)
0lvqu8t6xm3xxddu19o/tm3qztk1xejhc2u2nl3ms8yjoscjuqop

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.