• <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>

            逛奔的蝸牛

            我不聰明,但我會很努力

               ::  :: 新隨筆 ::  ::  :: 管理 ::

            Base64是網絡上最常見的用于傳輸8Bit字節代碼的編碼方式之一,在發送電子郵件時,服務器認證的用戶名和密碼需要用Base64編碼,附件也需要用Base64編碼。
            下面簡單介紹Base64算法的原理,由于代碼太長就不在此貼出
            Base64要求把每三個8Bit的字節轉換為四個6Bit的字節(3*8 = 4*6 = 24),然后把6Bit再添兩位高位0,組成四個8Bit的字節,也就是說,轉換后的字符串理論上將要比原來的長1/3。
            轉換后,我們用一個碼表來得到我們想要的字符串(也就是最終的Base64編碼),這個表是這樣的:
            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 
            6 G 23 X 40 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 32 g 49 x 
            16 Q 33 h 50 y 
            原文的字節最后不夠3個的地方用0來補足,轉換時Base64編碼用=號來代替。這就是為什么有些Base64編碼會以一個或兩個等號結束的原因,但等號最多只有兩個。
            舉一個例子,abc經過Base64編碼以后的結果是YWJj.
            
            發郵件的時候所寫的信息自動在后臺轉換然后傳輸... 




            各位看官應該都是資深的網蟲了,小弟斗膽在此問問大家,平時上網時,除了泡MM、到論壇灌水、扔版磚……之外,進行的最多的是什么活動?對了,你一定會說:是收發電子郵件!(誰敢說自己沒收/發過電子郵件的?拉出去槍斃了!!)

            收/發E-mail的時候有一個安全性的問題——假想一下,你花了一整天時間給系花寫的情書,在發送的過程中被隔壁宿舍張三那小子截獲了(難道他是黑客??),更糟的是他是你的情敵啊……天,后果不堪設想!!因此,我們必須有一種比較可靠的加密方法,能夠對電子郵件的明文進行轉換,至少要得出一個無法被別人一眼就看出內容來的東西,而且編碼/解碼的速度還要足夠快。(這時你可以再假想一下啦,張三那家伙截獲了你的肉麻情書,可是他一看:“咦?怎么亂七八糟的?垃圾郵件!!”——這樣一來你不就逃過大難了?!)

            Base64就是在這種背景下產生的加密方法。它的特點是:1、速度非常快。2、能夠將字符串A轉換成字符串B,而且如果你光看字符串B,是絕對猜不出字符串A的內容來的。不信嗎?讓我們來看看下面這串東西:

            xOO6w6Osu7bTrbniwdnAz8LetcTnzbfXzOy12KOh

            呵呵,是什么啊?猜出來了嗎?其實它就是下面這段文字經過Base64編碼產生的東東:

            你好,歡迎光臨老羅的繽紛天地!

            介紹說完啦,讓我們開始探討實質性的東西。

            Base64是網絡上最常見的用于傳輸8Bit字節代碼的編碼方式之一,大家可以查看RFC2045~RFC2049,上面有MIME的詳細規范。

            Base64要求把每三個8Bit的字節轉換為四個6Bit的字節(3*8 = 4*6 = 24),然后把6Bit再添兩位高位0,組成四個8Bit的字節,也就是說,轉換后的字符串理論上將要比原來的長1/3。

            這樣說會不會太抽象了?不怕,我們來看一個例子:

            轉換前aaaaaabbccccddddeeffffff
            轉換后00aaaaaa00bbcccc00ddddee00ffffff

            應該很清楚了吧?上面的三個字節是原文,下面的四個字節是轉換后的Base64編碼,其前兩位均為0。

            轉換后,我們用一個碼表來得到我們想要的字符串(也就是最終的Base64編碼),這個表是這樣的:(摘自RFC2045)


                                        Table 1: The Base64 Alphabet

                  Value Encoding  Value Encoding  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
                       6 G            23 X            40 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            32 g            49 x
                      16 Q            33 h            50 y


            讓我們再來看一個實際的例子,加深印象!

            轉換前101011011011101001110110
            轉換后00101011000110110010100100110110
            十進制43274154
            對應碼表中的值rbp2


            所以上面的24位編碼,編碼后的Base64值為 rbp2
            解碼同理,把 rbq2 的二進制位連接上再重組得到三個8位值,得出原碼。
            (解碼只是編碼的逆過程,在此我就不多說了,另外有關MIME的RFC還是有很多的,如果需要詳細情況請自行查找。)

            用更接近于編程的思維來說,編碼的過程是這樣的:

            第一個字符通過右移2位獲得第一個目標字符的Base64表位置,根據這個數值取到表上相應的字符,就是第一個目標字符。
            然后將第一個字符左移4位加上第二個字符右移4位,即獲得第二個目標字符。
            再將第二個字符左移2位加上第三個字符右移6位,獲得第三個目標字符。
            最后取第三個字符的右6位即獲得第四個目標字符。

            在以上的每一個步驟之后,再把結果與 0x3F 進行 AND 位操作,就可以得到編碼后的字符了。

            (感謝 Athena 指出以上描述中原有的一些錯誤!^_^)

            So easy! That’s all!!!

            可是等等……聰明的你可能會問到,原文的字節數量應該是3的倍數啊,如果這個條件不能滿足的話,那該怎么辦呢?

            我們的解決辦法是這樣的:原文的字節不夠的地方可以用全0來補足,轉換時Base64編碼用=號來代替。這就是為什么有些Base64編碼會以一個或兩個等號結束的原因,但等號最多只有兩個。因為:

            余數 = 原文字節數 MOD 3

            所以余數任何情況下都只可能是0,1,2這三個數中的一個。如果余數是0的話,就表示原文字節數正好是3的倍數(最理想的情況啦)。如果是1的話,為了讓Base64編碼是4的倍數,就要補2個等號;同理,如果是2的話,就要補1個等號。

            講到這里,大伙兒應該全明白了吧?如果還有不清楚的話就返回去再仔細看看,其實不難理解的。

            下面我給出一個演示Base64編碼/解碼的程序,希望能對您有用。同時也希望您幫我完善它,利用它做出更多的用途,到時別忘了通知我一聲啊!(我現在太忙了)


            DLL的源代碼:Base64Dll.asm

            ;***********************************************
            ;程序名稱:演示Base64編碼/解碼原理
            ;作者:羅聰
            ;日期:2002-9-14
            ;出處:http://laoluoc.yeah.net(老羅的繽紛天地)
            ;注意事項:如欲轉載,請保持本程序的完整,并注明:
            ;轉載自“老羅的繽紛天地”(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


            ;**********************************************************
            ;函數功能:進行Base64編碼
            ;參數:
            ;    source          =    傳入的字符串
            ;    destination     =    返回的編碼
            ;**********************************************************
            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


            ;**********************************************************
            ;函數功能:進行Base64解碼
            ;參數:
            ;    source          =    傳入的編碼
            ;    destination     =    返回的字符串
            ;**********************************************************
            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





            測試程序:base64.asm

            ;***********************************************
            ;程序名稱:演示Base64編碼/解碼原理
            ;作者:羅聰
            ;日期:2002-9-14
            ;出處:http://laoluoc.yeah.net(老羅的繽紛天地)
            ;注意事項:如欲轉載,請保持本程序的完整,并注明:
            ;轉載自“老羅的繽紛天地”(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)
            szTemplate_Encode    db    "字符串 ""%s"" 的Base64編碼是:", 13, 10, 13, 10, "%s", 0
            szTemplate_Decode    db    "編碼 ""%s"" 經過Base64還原后的字符串是:", 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
                            ;取得用戶輸入的字符串:
                            invoke GetDlgItemText, hWnd, IDC_EDIT_INPUT, addr szBuffer, 255

                            ;進行 ASCII->Base64 轉換:
                            invoke Base64Encode, addr szBuffer, addr szText

                            ;格式化輸出:
                            invoke wsprintf, addr szMsg, addr szTemplate_Encode, addr szBuffer, addr szText

                            ;顯示結果:
                            invoke MessageBox, hWnd, addr szMsg, addr szCaption, MB_OK

                        .elseif eax == IDC_BUTTON_DECODE
                            ;取得用戶輸入的字符串:
                            invoke GetDlgItemText, hWnd, IDC_EDIT_INPUT, addr szBuffer, 255

                            ;進行 Base64->ASCII 轉換:
                            invoke Base64Decode, addr szBuffer, addr szText

                            ;格式化輸出:
                            invoke wsprintf, addr szMsg, addr szTemplate_Decode, addr szBuffer, addr szText

                            ;顯示結果:
                            invoke MessageBox, hWnd, addr szMsg, addr szCaption, MB_OK
                        .endif

                        ;全選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





            測試程序的資源文件: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           "請輸入字符串:", IDC_STATIC, 11, 7, 130, 10
                EDITTEXT        IDC_EDIT_INPUT, 11, 20, 173, 12, ES_AUTOHSCROLL
                DEFPUSHBUTTON   "編碼(&E)", IDC_BUTTON_ENCODE, 38, 39, 52, 15
                PUSHBUTTON      "解碼(&D)", IDC_BUTTON_DECODE, 104, 39, 52, 15
            END


            如果你發現了有bug,一定要告訴我啊,并請來信討論!lcother@163.net

            最后給大家留下一個小小的習題,你知道下面這串Base64編碼的原文是什么嗎?  :)
            posted on 2009-11-04 02:43 逛奔的蝸牛 閱讀(917) 評論(0)  編輯 收藏 引用 所屬分類: 其他編程
            成人亚洲欧美久久久久| 亚洲人成精品久久久久| 久久成人国产精品| 久久久女人与动物群交毛片| 久久精品国产男包| 久久婷婷人人澡人人爽人人爱| 免费一级做a爰片久久毛片潮| 国内精品久久久久久久久电影网| 人人狠狠综合久久亚洲88| 久久r热这里有精品视频| 久久精品国产亚洲麻豆| 精品熟女少妇aⅴ免费久久| 久久久久黑人强伦姧人妻| 亚洲精品tv久久久久| 久久久无码精品亚洲日韩蜜臀浪潮| 中文字幕亚洲综合久久菠萝蜜| 久久久这里有精品| 人妻丰满AV无码久久不卡 | 久久免费美女视频| 91久久香蕉国产熟女线看| 久久男人中文字幕资源站| 理论片午午伦夜理片久久| av色综合久久天堂av色综合在| 日产精品久久久久久久性色| 久久综合狠狠综合久久激情 | 久久青青国产| 久久婷婷激情综合色综合俺也去| 97久久精品午夜一区二区| 欧美精品丝袜久久久中文字幕 | 2021最新久久久视精品爱| 亚洲日本va中文字幕久久| 精品久久久久久国产91| 亚洲欧美日韩久久精品| 69国产成人综合久久精品| 国产精品永久久久久久久久久| 伊人久久精品无码av一区| 亚洲国产天堂久久综合网站| 一本色道久久HEZYO无码| 久久国产精品免费| 久久99国内精品自在现线| 伊人久久大香线蕉无码麻豆|