base64加密原理及python、C语言代码实现
base64算法
base64加密原理
關于base64,百度百科給出的解釋是:
Base64是網絡上最常見的用于傳輸8Bit字節碼的編碼方式之一,Base64就是一種基于64個可打印字符來表示二進制數據的方法。可查看RFC2045~RFC2049,上面有MIME的詳細規范。
 Base64編碼是從二進制到字符的過程,可用于在HTTP環境下傳遞較長的標識信息。采用Base64編碼具有不可讀性,需要解碼后才能閱讀。
 Base64由于以上優點被廣泛應用于計算機的各個領域,然而由于輸出內容中包括兩個以上“符號類”字符(+, /, =),不同的應用場景又分別研制了Base64的各種“變種”。為統一和規范化Base64的輸出,Base62x被視為無符號化的改進版本。
base64中的這64個可打印字符包括小寫的a?za-za?z和大寫的A?ZA-ZA?Z,依舊數字0?90-90?9以及兩個符號“+"和“/"“+"和“/"“+"和“/"。選擇64這個數字是因為64是2的6次方,正好可以用6位二進制編號,所以這64個字符在這里的編號不同于在ASCII中的編號了,應該為:
 
 要先明確,base64的加密對象是二進制串
加密過程是:將三個字節 (共3*8=24位) 的二進制轉換為四個字符
例如:
 原來的二進制數是:1111 1111, 1111 1111, 1111 1111 (二進制)
 轉換后 0011 1111, 0011 1111, 0011 1111, 0011 1111 (二進制)
 十進制為:63,63,63,63
 對應上面碼表的字符為////////
 所以上面的24位編碼,編碼后的Base64值為////////
再來一個例子:
 原來的二進制數是:1010 1101,1011 1010,0111 0110(二進制)
 轉換后 0010 1011, 0001 1011 ,0010 1001 ,0011 0110(二進制)
 十進制為:43 27 41 54
 對應上面碼表的字符為rbp2rbp2rbp2
 所以上面的24位編碼,編碼后的Base64值為rbp2rbp2rbp2
 解碼同理,把rbq2rbq2rbq2的二進制位連接上再重組得到三個8位值,得出原碼。
base加密在python中可以直接調用庫:base64,例如:
 (知道Base是對二進制數進行加密的,所以在對字母進行加密是就需要先將字母轉化為數字)
C 語言實現
// base64.cpp #include <iostream> #include <windows.h> #include "Base64.h"using namespace std;char *base64_encode(const char* data, int data_len) { //int data_len = strlen(data); int prepare = 0; int ret_len; int temp = 0; char *ret = NULL; char *f = NULL; int tmp = 0; char changed[4]; int i = 0; ret_len = data_len / 3; temp = data_len % 3; if (temp > 0) { ret_len += 1; } ret_len = ret_len*4 + 1; ret = (char *)malloc(ret_len); if ( ret == NULL) { printf("No enough memory.\n"); exit(0); } memset(ret, 0, ret_len); f = ret; while (tmp < data_len) { temp = 0; prepare = 0; memset(changed, '\0', 4); while (temp < 3) { //printf("tmp = %d\n", tmp); if (tmp >= data_len) { break; } prepare = ((prepare << 8) | (data[tmp] & 0xFF)); tmp++; temp++; } prepare = (prepare<<((3-temp)*8)); //printf("before for : temp = %d, prepare = %d\n", temp, prepare); for (i = 0; i < 4 ;i++ ) { if (temp < i) { changed[i] = 0x40; // 瀵瑰簲鐮佽〃涓殑 '=' } else { changed[i] = (prepare>>((3-i)*6)) & 0x3F; } *f = base[changed[i]]; //printf("%.2X", changed[i]); f++; } } *f = '\0'; return ret; } static char find_pos(char ch) { char *ptr = (char*)strrchr(base, ch);//the last position (the only) in base[] return (ptr - base); } char *base64_decode(const char *data, int data_len) { int ret_len = (data_len / 4) * 3; int equal_count = 0; char *ret = NULL; char *f = NULL; int tmp = 0; int temp = 0;int prepare = 0; int i = 0; if (*(data + data_len - 1) == '=') { equal_count += 1; } if (*(data + data_len - 2) == '=') { equal_count += 1; } if (*(data + data_len - 3) == '=') {//seems impossible equal_count += 1; } switch (equal_count) { case 0: ret_len += 4;//3 + 1 [1 for NULL] break; case 1: ret_len += 4;//Ceil((6*3)/8)+1 break; case 2: ret_len += 3;//Ceil((6*2)/8)+1 break; case 3: ret_len += 2;//Ceil((6*1)/8)+1 break; } ret = (char *)malloc(ret_len); if (ret == NULL) { printf("No enough memory.\n"); exit(0); } memset(ret, 0, ret_len); f = ret; while (tmp < (data_len - equal_count)) { temp = 0; prepare = 0; while (temp < 4) { if (tmp >= (data_len - equal_count)) { break; } prepare = (prepare << 6) | (find_pos(data[tmp])); temp++; tmp++; } prepare = prepare << ((4-temp) * 6); for (i=0; i<3 ;i++ ) { if (i == temp) { break; } *f = (char)((prepare>>((2-i)*8)) & 0xFF); f++; } } *f = '\0'; return ret; }int main() {char text[200];printf("請輸入待加密字符:");int i=0;do{scanf("%s",&text[i]); i++;}while(getchar()!='\n');printf("%s\n", base64_encode(text, strlen(text)));return 0; } // base64.h#ifndef BASE64_H #define BASE64_Hconst char base[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/="; char* base64_encode(const char* data, int data_len); char *base64_decode(const char* data, int data_len); #endif代碼參考
python實現
利用庫
import base64 s = input() a = base64.b64encode(s.decode()) print(a)原理實現
class MyBase64():base64_dict = {}string_temp = ('ABCDEFGHIJKLMNOPQRSTUVWXYZ''abcdefghijklmnopqrstuvwxyz''0123456789+/')ascii_string = ''.join([chr(i) for i in range(4, 2 ** 7 - 1)])def __init__(self, string):# 初始化,創建 base64 編碼字典self.string = stringfor i in range(2 ** 6):self.base64_dict[i] = self.string_temp[i]def convert(self):# base64 編碼過程# 編碼string_encode_byte = self.string.encode('utf-8')# 十進制化string_digit_list = list(string_encode_byte)# 二進制化 + 0 填充string_bin_list = []for item in string_digit_list:string_bin_list.append(str(bin(item))[2:].zfill(8))# 字符串合并string_sum = ''.join(string_bin_list)# 6 的倍數,不足 0 填充string_fill = self.fillIt(string_sum, factor=6, item='0')# 切片,6位一個單位string_bin_list2 = self.splitIt(string_fill, bits=6)# 十進制化string_digit_list2 = []for item in string_bin_list2:string_digit_list2.append(int(item, 2))# 查表string_base64_list = []for item in string_digit_list2:string_base64_list.append(self.base64_dict[item])# 拼接string_sum2 = ''.join(string_base64_list)# 4 的倍數,不足填充 =string_convert = self.fillIt(string_sum2, factor=4, item='=')return string_convertdef fillIt(self, string, factor, item):"""指定倍數填充指定字符string:原字符串factor:倍數item:填充字符"""length = len(string)remainder = length % factorif remainder:times = factor - remainderstring = string + times * itemreturn stringdef splitIt(self, string, bits):"""指定位數切片string:原字符串bits:每次切片數量"""length = len(string)new_list = []for i in range(bits, length + 1, bits):new_list.append(string[i - bits:i])remain = length % bitsif remain != 0:new_list.append(string[-remain:])return new_listif __name__ == '__main__':string = input()myBase64 = MyBase64(string)enc_string = myBase64.convert()print("測試字符串:{}".format(string))print("base64:{}".format(enc_string))代碼參考
拓展:base隱寫
base64之所以可以隱藏信息,便是在于在解密過程中,在解碼的第3步中,會有部分數據被丟棄(即不會影響解碼結果),這些數據正是在編碼過程中補的0。也就是說,如果在編碼過程中不全用0填充,而是用其他的數據填充,仍然可以正常編碼解碼,因此這些位置可以用于隱寫。
解開隱寫的方法就是將這些不影響解碼結果的位提取出來組成二進制串(一行 base64 最多有 2 個等號, 也就是有 22 位的可隱寫位.),然后轉換成ASCII字符串。這就是為什么出base64隱寫時會有很多大段 base64 的原因
原理及代碼參考
def get_base64_diff_value(s1, s2):base64chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'res = 0for i in xrange(len(s2)):if s1[i] != s2[i]:return abs(base64chars.index(s1[i]) - base64chars.index(s2[i]))return resdef solve_stego():with open('shy.txt', 'rb') as f:file_lines = f.readlines()bin_str = ''for line in file_lines:steg_line = line.replace('\n', '')norm_line = line.replace('\n', '').decode('base64').encode('base64').replace('\n', '')diff = get_base64_diff_value(steg_line, norm_line)print diffpads_num = steg_line.count('=')if diff:bin_str += bin(diff)[2:].zfill(pads_num * 2)else:bin_str += '0' * pads_num * 2print goflag(bin_str)def goflag(bin_str):res_str = ''for i in xrange(0, len(bin_str), 8):res_str += chr(int(bin_str[i:i + 8], 2))return res_strif __name__ == '__main__':solve_stego()總結
以上是生活随笔為你收集整理的base64加密原理及python、C语言代码实现的全部內容,希望文章能夠幫你解決所遇到的問題。
                            
                        - 上一篇: 2022-01-04
 - 下一篇: 2022-01-06