base64编码和解码算法

目录

一、概述

二、原理

三、算法源码

四、TK版源码


一、概述

      Base64编码是一种基于64个可打印字符来表示二进制数据的方法。
  为什么会有Base64编码呢?因为有些网络传送渠道并不支持所有的字节,例如:传统的邮件只支持可见字符的传送,像ASCII码的控制字符就不能通过邮件传送。这样用途就受到了很大的限制。图片的二进制流的每个字节不可能全部是可见字符,这就导致图片的二进制流无法传送。最好的解决方式就是在不改变传统协议的情况下,做一种扩展方案来支持二进制文件的传送。即把不可打印的字符也能用可打印字符来表示,问题就解决了。Base64编码就是为了实现这一方案而设计的编码格式。
  Base64就是一种基于64个可打印字符来表示二进制数据的表示方法。   

二、原理

1.通过将待转换的字符串每三个字节分为一组,每个字节占8个二进制位,那么共有24个二进制位。

2.每24个二进制位分为每6个一组,则每3个字节可分为4组

3.在每组前面添加两个0,每组由6个二进制位变为8个二进制位,总共32个二进制位,即四个字节。

4.根据Base64编码索引表获得对应的值。

索引表

base64编码和解码算法_第1张图片

原理图1:

base64编码和解码算法_第2张图片 

原理图2:

base64编码和解码算法_第3张图片

 

三、算法源码


IndexTable='ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'

#base64加密算法
import base64

#base64算法编码:byte-->str
def encryption(byteData):
    # 打印字节数据
    print('byte数据: ', byteData)
    # print(len(byteData))

    #将字节数据转为二进制数
    binData = ''
    for i in byteData:
        #每个字节二进制记得左侧补零
        binData = binData + bin(i)[2:].zfill(8)
    print('转后二进制数: ', binData)

    #每3个字节24位,右侧补零
    fillZero = (24 - len(binData) % 24) % 24
    print('补零数: ', fillZero)
    binData = binData + ''.zfill(fillZero)
    print('补零后二进制数: ', binData)

    #每6位进行一次编码
    pos = 0
    resStr = ''
    print('每六位的值进行索引编码:')
    while(True):
        if pos>=len(binData):
            break
        sixBin = binData[pos:pos+6]
        print(sixBin.zfill(8))
        indexOfNum = int(sixBin.zfill(8), 2)
        resStr = resStr + IndexTable[indexOfNum]
        pos = pos + 6

    # 补零数如果需要8位,最终结果最后一位A替换一个等号。  16位,最终结果最后二位AA替换为二个等号。
    if fillZero == 8:
        resStr = resStr[:-1] + '='
    elif fillZero == 16:
        resStr = resStr[:-2] + '=='

    return resStr

#base64解密算法
def decryption(base64Str):
    binDataStr = ''
    for j in base64Str:
        #查出每个字符在索引表中的值
        index = IndexTable.find(j)

        #将值转为2进制数
        if index != -1:
            binDataStr = binDataStr + bin(index)[2:].zfill(6)
        else:
            binDataStr = binDataStr + '000000'
    print('解码后二进制数: ', binDataStr)

    #如果是1个等号,去掉1个自己8个0, 2个等号,去掉2个字节16个0
    if base64Str.count('=') == 1:
        binDataStr = binDataStr[:-8]
    elif base64Str.count('=') == 2:
        binDataStr = binDataStr[:-16]
    print('去零后二进制数: ', binDataStr)

    print('每八位取ascii值:')
    pos = 0
    resHex = ''
    while(True):
        if pos >= len(binDataStr):
            break
        eightBin = binDataStr[pos:pos+8]
        print(eightBin)
        # 转为十进制
        indexOfNum = int(eightBin, 2)
        # 转为16进制,并拼接
        resHex = resHex + hex(indexOfNum).replace('0x', '')
        pos = pos + 8
    print('转为16进制字符串: ', resHex)

    #将每个字节的16进制转为字节串
    byteContent = bytes().fromhex(resHex)
    print('转为字节串: ', byteContent)

    #utf-8解码,最终结果
    res = byteContent.decode('utf-8')
    return res



content = '我的ab'

#python自带base64编码
contentToByte = content.encode('utf-8')
base64_data = base64.b64encode(contentToByte)
print('python自带base64编码: ', base64_data.decode('utf-8'))

#python自带base64解码
contentByte = base64.b64decode(base64_data)
print('python自带base64解码: ', contentByte.decode('utf-8'))

#base64算法编码
print('*'*20, '以下为编码过程', '*'*20)
print('原文: ', content)
contentToByte = content.encode('utf-8')
encryContent = encryption(contentToByte)
print('base64算法编码:', encryContent)

#base64算法解码
print('*'*20, '以下为解码过程', '*'*20)
decryContent = decryption(encryContent)
print('base64算法解码:', decryContent)

四、TK版源码

#!/usr/bin/env python
# Author:Veray Zhou

import tkinter as tk

IndexTable='ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'

#base64算法编码:byte-->str
def encryption(byteData):
    # 打印字节数据
    print('byte数据: ', byteData)
    # print(len(byteData))

    #将字节数据转为二进制数
    binData = ''
    for i in byteData:
        #每个字节二进制记得左侧补零
        binData = binData + bin(i)[2:].zfill(8)
    print('转后二进制数: ', binData)

    #每3个字节24位,右侧补零
    fillZero = (24 - len(binData) % 24) % 24
    print('补零数: ', fillZero)
    binData = binData + ''.zfill(fillZero)
    print('补零后二进制数: ', binData)

    #每6位进行一次编码
    pos = 0
    resStr = ''
    print('每六位的值进行索引编码:')
    while(True):
        if pos>=len(binData):
            break
        sixBin = binData[pos:pos+6]
        print(sixBin.zfill(8))
        indexOfNum = int(sixBin.zfill(8), 2)
        resStr = resStr + IndexTable[indexOfNum]
        pos = pos + 6

    # 补零数如果需要8位,最终结果最后一位A替换一个等号。  16位,最终结果最后二位AA替换为二个等号。
    if fillZero == 8:
        resStr = resStr[:-1] + '='
    elif fillZero == 16:
        resStr = resStr[:-2] + '=='

    return resStr

#base64解密算法
def decryption(base64Str):
    binDataStr = ''
    for j in base64Str:
        #查出每个字符在索引表中的值
        index = IndexTable.find(j)

        #将值转为2进制数
        if index != -1:
            binDataStr = binDataStr + bin(index)[2:].zfill(6)
        else:
            binDataStr = binDataStr + '000000'
    print('解码后二进制数: ', binDataStr)

    #如果是1个等号,去掉1个自己8个0, 2个等号,去掉2个字节16个0
    if base64Str.count('=') == 1:
        binDataStr = binDataStr[:-8]
    elif base64Str.count('=') == 2:
        binDataStr = binDataStr[:-16]
    print('去零后二进制数: ', binDataStr)

    print('每八位取ascii值:')
    pos = 0
    resHex = ''
    while(True):
        if pos >= len(binDataStr):
            break
        eightBin = binDataStr[pos:pos+8]
        print(eightBin)
        # 转为十进制
        indexOfNum = int(eightBin, 2)
        # 转为16进制,并拼接
        resHex = resHex + hex(indexOfNum).replace('0x', '')
        pos = pos + 8
    print('转为16进制字符串: ', resHex)

    #将每个字节的16进制转为字节串
    byteContent = bytes().fromhex(resHex)
    print('转为字节串: ', byteContent)

    #utf-8解码,最终结果
    res = byteContent.decode('utf-8')
    return res




window = tk.Tk()
window.title('BASE64编码和解码算法')
window.geometry('600x800')

def encry():
    content = t.get('1.0','end')[:-1]
    contentToByte = content.encode('utf-8')
    encryContent = encryption(contentToByte)
    t1.delete('1.0', 'end')
    t1.insert(1.0, encryContent)

def decry():
    encryContent = t1.get('1.0','end')[:-1]
    decryContent = decryption(encryContent)
    t2.delete('1.0', 'end')
    t2.insert(1.0, decryContent)



tk.Label(window, text='请输入文本内容: ').pack()


t = tk.Text(window, height=10)
t.pack()

b = tk.Button(window, text='BASE64编码', command=encry)
b.pack()



t1 = tk.Text(height=20)
t1.pack()


b = tk.Button(window, text='BASE64解码', command=decry)
b.pack()

t2 = tk.Text(height=20)
t2.pack()




window.mainloop()



base64编码和解码算法_第4张图片

 

 

你可能感兴趣的:(Python学习,密码学,python,算法,base64编码)