Base64么新鮮的算法了。只是假設你沒從事過頁面開發(或者說動態頁面開發。尤其是郵箱服務),你都不怎么了解過,僅僅是聽起來非常熟悉。
對於黑客來說,Base64與MD5算法有着相同的位置。由於電子郵箱(e-mail)正文就是base64編碼的。
那么。我們就一起來深入的探討一下這個東東吧。
對於一種算法,與其問“它是什么?”,不如問“它實現了什么?”
Base64實現了:將隨意字節轉為可讀字符的編碼。
我們知道。除了頁面上的文本,計算機中的數據還有非常多是不可見的。那么我們再扯一扯編碼的問題吧。
通俗的說,編碼就是給某個文字符號邊上一個數字序號,計算機在現實這個文字符號(字符)的時候,依據這個序號到字庫中查找相應的點陣或矢量數據,
在顯示器上“畫”出來。(關於點陣和矢量我們就不扯了。不然就真的太遠了。
)
起初的字符編碼,沒有把漢字、日文、朝鮮文和其它文字包含在內,僅僅有26個英文字母的大寫和小寫和10個阿拉伯數字。加上一些控制字符和空格,用一個字節
就行全然的編碼了。(不要告訴我你不知道2的7次方和2的8次方是多少,一個技術人員為這種問題困擾簡直是一種恥辱。)
然而。世界上除了文字還有數據。比方圖片、壓縮文件、程序等等都是二進制文件。這些文件一樣以字節為單位存儲數據。這些字節往往不不過2的7次方以內
的可顯示的文字字符編碼,還有可能是大於127(有符號數小於0)的字節,這些字節沒辦法用字符顯示出來,Base64就是通過某種算法將他們顯示出來。
*那么,Base64加密是安全的嗎?
沒有絕對安全的加密。Base64不是為了安全,而是為了顯示。並且Base64是可逆的。也就是說。通過簡單的解密就能得到原文。事實上即便是不可逆的MD5算法。
也能夠通過明文數據庫找出可能的原文(睡到知道e10adc3949ba59abbe56e057f20f883e的原文就是123456)。
*那么,Base64是怎么實現的呢?
事實上非常easy,只是為了URL等特殊用處,Base64選擇了下面64個字符作為密文顯示,着64個字符都是可顯示的,他們是:
ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/
假設密文有不屬於他們的字符,那么不是Base64編碼或者是山寨版的。
一眼看去就知道是26個字母大寫和小寫和數字,加上“+”“/”兩個符號。“?
*-”因為正則表達式的問題,沒有選用,而空格和回車這些是不能顯示的。
Base64處理的過程是,以3個字節為一組(3個字節就是24位嘛),每6位擴展成8位得到4個字節(就是32位):
11111111 11111111 11111111 -> 111111 111111 111111 111111 -> 00111111 00111111 00111111 00111111
那么,得到的每個字節,最大也就是2的6次方。
或許你說:哇,小於2的7次方,能夠顯示了。
事實上不是,得到的這2的6次方式上面那一串字符的索引,也就是說每一個字節的值僅僅是代表它在密文表中的位置。比方
字符“a”的編碼是97。 用16進制表示是0x61(VB表示為&H61)。二進制:01100001,由於不足3位。補0得到 00011000 00010000 000……
前兩個字節是十進制的24 和 16,那么相應那一串字符中的第24個字符和第16個字符為:YQ(索引從0開始算),那么單獨“a”的Base64編碼為
YQ==(不足3為的每一個字符直接轉為“=”)。簡單吧!
有了算法,解碼的過程就各位聰明特達的程序猿取思考思考吧,最后C/C++版的編碼和解碼代碼貼上。
- /******************************************
- Base64編碼解碼算法 C語言源碼
- by 虎膽游俠 http://blog.csdn.net/prsniper
- ******************************************/
- #include <stdio.h> //注意哦,VC中""是當前路徑。<>是系統路徑
- #include <windows.h>
- const char BASE_CODE[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
- //編碼,參數:要編碼的字符串指針,解碼后存放的位置(編碼字串長度的4/3),要編碼的字符串長度 ->返回結果長度
- int fnBase64Encode(char *lpString, char *lpBuffer, int sLen)
- { register int vLen = 0; //寄存器局部變量,提速
- while(sLen > 0) //處理整個字符串
- { *lpBuffer++ = BASE_CODE[(lpString[0] >> 2 ) & 0x3F]; //右移兩位,與00111111是防止溢出,自加
- if(sLen > 2) //夠3個字符
- { *lpBuffer++ = BASE_CODE[((lpString[0] & 3) << 4) | (lpString[1] >> 4)];
- *lpBuffer++ = BASE_CODE[((lpString[1] & 0xF) << 2) | (lpString[2] >> 6)];
- *lpBuffer++ = BASE_CODE[lpString[2] & 0x3F];
- }else
- { switch(sLen) //追加“=”
- { case 1:
- *lpBuffer ++ = BASE_CODE[(lpString[0] & 3) << 4 ];
- *lpBuffer ++ = '=';
- *lpBuffer ++ = '=';
- break;
- case 2:
- *lpBuffer ++ = BASE_CODE[((lpString[0] & 3) << 4) | (lpString[1] >> 4)];
- *lpBuffer ++ = BASE_CODE[((lpString[1] & 0x0F) << 2) | (lpString[2] >> 6)];
- *lpBuffer ++ = '=';
- break;
- }
- }
- lpString += 3;
- sLen -= 3;
- vLen +=4;
- }
- *lpBuffer = 0;
- return vLen;
- }
- //子函數 - 取密文的索引
- inline char GetCharIndex(char c) //內聯函數能夠省去函數調用過程。提速
- { if((c >= 'A') && (c <= 'Z'))
- { return c - 'A';
- }else if((c >= 'a') && (c <= 'z'))
- { return c - 'a' + 26;
- }else if((c >= '0') && (c <= '9'))
- { return c - '0' + 52;
- }else if(c == '+')
- { return 62;
- }else if(c == '/')
- { return 63;
- }else if(c == '=')
- { return 0;
- }
- return 0;
- }
- //解碼,參數:結果,密文,密文長度
- int fnBase64Decode(char *lpString, char *lpSrc, int sLen) //解碼函數
- { static char lpCode[4];
- register int vLen = 0;
- if(sLen % 4) //Base64編碼長度必然是4的倍數,包含'='
- { lpString[0] = '\0';
- return -1;
- }
- while(sLen > 2) //不足三個字符。忽略
- { lpCode[0] = GetCharIndex(lpSrc[0]);
- lpCode[1] = GetCharIndex(lpSrc[1]);
- lpCode[2] = GetCharIndex(lpSrc[2]);
- lpCode[3] = GetCharIndex(lpSrc[3]);
- *lpString++ = (lpCode[0] << 2) | (lpCode[1] >> 4);
- *lpString++ = (lpCode[1] << 4) | (lpCode[2] >> 2);
- *lpString++ = (lpCode[2] << 6) | (lpCode[3]);
- lpSrc += 4;
- sLen -= 4;
- vLen += 3;
- }
- return vLen;
- }
- void main() //主函數,測試函數
- { char s[] = "a", str[32];
- int l = strlen(s);
- int i = fnBase64Encode(s, str, l);
- printf("fnBase64Encode(\"%s\", str, %d) = \"%s\";\n", s, l, str);
- l = fnBase64Decode(s, str, i);
- printf("fnBase64Decode(\"%s\", s, %d) = \"%s\";\n", str, i, s);
- }
編譯為控制台應用程序,執行如圖:
原文地址:http://blog.csdn.net/prsniper/article/details/7097643
版權聲明:本文博主原創文章,博客,未經同意不得轉載。