详细请看:https://www.cnblogs.com/0yst3r-2046/p/11962942.html
本文参考:https://blog.csdn.net/Sciurdae/article/details/133642336
Base16
base16编码也称为十六进制编码或Hex编码,是一种将二进制数据表示为十六进制数字和字符的方法。它使用16个字符(0-9和A-F)来表示4位二进制数的每个组合。
编码原理:
由于4bit就可以表示2^4 = 16个字符。所以用4bit可以表示所有的十六进制数。
1byte=8bit 所以1byte = 俩个十六进制数据。
这里就涉及一个字节序的问题:是用大端模式还是小端模式?Base16编码明确表明是用小端模式存储。
编码过程:
1.将二进制数据分割为4个一组
2.映射,将每四位二进制数据映射到对应的base16字符。如下:
0000 -> 0
0001 -> 1
0010 -> 2
0011 -> 3
0100 -> 4
0101 -> 5
0110 -> 6
0111 -> 7
1000 -> 8
1001 -> 9
1010 -> A
1011 -> B
1100 -> C
1101 -> D
1110 -> E
1111 -> F
3.编码
4.填充(可选):若二进制数据不是4的倍数,就在后面填充0;
base32编码
Base32编码是一种将二进制数据转换为使用32个不同字符表示的文本编码方式
由于5bit就可以表示2^5 = 32个字符。所以base32就是将二进制数据分割成5个一组,如果结尾不满足5的倍数,就用“=”填充,之后再根据base32索引表,进行编码。
base32索引表:
00000 -> A
00001 -> B
00010 -> C
00011 -> D
00100 -> E
00101 -> F
00110 -> G
00111 -> H
01000 -> I
01001 -> J
01010 -> K
01011 -> L
01100 -> M
01101 -> N
01110 -> O
01111 -> P
10000 -> Q
10001 -> R
10010 -> S
10011 -> T
10100 -> U
10101 -> V
10110 -> W
10111 -> X
11000 -> Y
11001 -> Z
11010 -> 2
11011 -> 3
11100 -> 4
11101 -> 5
11110 -> 6
11111 -> 7
Base32编码通常用于需要在文本环境中表示二进制数据的场景,例如电子邮件中的附件编码、URL中的参数传递等。
base58编码
Base58编码是一种将二进制数据转换为文本编码的方法,通常用于表示加密货币地址和其他数据。
原理:
1、准备要编码的二进制数据: 将要编码的二进制数据准备好,通常是字节的形式。
2、添加版本前缀(可选): 在某些应用中,可以在二进制数据前添加一个版本前缀,以标识数据的类型或用途。这是可选的步骤,具体取决于编码的需求。
3、计算校验和(可选): 在某些情况下,可以计算二进制数据的校验和并附加到数据的末尾,以增加数据的完整性和安全性。这也是可选的步骤。
4、Base58编码: 将经过前两步(添加版本前缀和计算校验和,如果适用)的二进制数据转换为Base58编码的文本。编码过程如下:
----------------------------------------------------------------------------------------------------------
Base58字符集通常包括58个字符,通常是由除去易混淆的字符(如0、O、I和l)以及可能引起歧义的字符(如+和/)的字符集构成。
将二进制数据视为一个大整数,使用Base58字符集中的字符作为数字的基数。
将大整数除以58,记录余数,并继续除以58,直到商为零。这将生成Base58编码的每个字符。
最后,反转生成的字符顺序以获得最终的Base58编码字符串。
输出Base58编码: 最终得到的Base58编码字符串就是表示输入二进制数据的文本表示形式。
-------------------------------------------------------------------------------------------------------
Base58编码的主要特点是它不包含易混淆的字符和可能引起歧义的字符,以增加可读性,并且在加密货币领域非常常见。请注意,Base58编码不是标准编码,不同的实现可能有略微不同的字符集和特殊规则。不同的加密货币可能会使用不同的Base58编码方案。
Base58索引表:

!base64编码!
Base64编码是一种将二进制数据转换为文本编码的方法,通常用于在文本协议中传输二进制数据,如电子邮件附件或在URL中传递数据。
原理:
1、准备要编码的二进制数据: 将要编码的二进制数据准备好,通常是字节的形式。
2、分组: 将二进制数据分成固定大小的组,每组通常为3字节(24位)。如果最后一组不足3字节,通常需要进行填充,以便每组都有3字节。
3、将每个组的二进制数据转换为十进制: 将每个3字节的二进制数据视为一个8bit*3=24bit位的二进制整数,再转化为一个十进制整数。
4、Base64编码: 将每个十进制整数编码为Base64字符。
1、Base64字符集通常包括64个字符,通常是大写字母A到Z、小写字母a到z、数字0到9以及两个额外的字符(通常是"+"和"/")。
2、以24位整数为例,将它分成4组,每组6位。这4组6位整数将被编码为4个Base64字符。
3 、每个6位整数对应一个Base64字符,根据其在Base64字符集中的位置来选择。
4、如果原始数据不足3字节,会添加一个或两个额外的0位,以确保每个6位整数都有6位。
5、Base64编码的结果是一个文本字符串,其中包含一系列Base64字符,每4个字符分为一组,每组表示一个24位整数。
填充(可选):如果原始数据的长度不是3的倍数,可以使用一个或两个填充字符“=”来补全Base64编码,以确保编码长度是4的倍数。
最终,Base64编码的结果就是表示输入二进制数据的文本字符串。在解码时,可以根据相同的算法将Base64编码的文本字符串还原为原始的二进制数据。
(Base64编码是一种常见的数据表示方式,用于在各种情境中传输和存储二进制数据,因为它可以将二进制数据转换为纯文本,并且广泛支持各种编程语言和应用程序。)
编码示例:(Man)

编码示例:(Base64的末尾补足)

Base64的索引表:
|Index | Character |Index | Character | Index | Character |Index | Character |
|0 | A | 16 | Q | 32 | g | 48 | w |
|1 | B | 17 | R | 33 | h | 49 | x |
|2 | C | 18 | S | 34 | i | 50 | y |
|3 | D | 19 | T | 35 | j | 51 | z |
|4 | E | 20 | U | 36 | k | 52 | 0 |
|5 | F | 21 | V | 37 | l | 53 | 1 |
|6 | G | 22 | W | 38 | m | 54 | 2 |
|7 | H | 23 | X | 39 | n | 55 | 3 |
|8 | I | 24 | Y | 40 | o | 56 | 4 |
|9 | J | 25 | Z | 41 | p | 57 | 5 |
|10 | K | 26 | a | 42 | q | 58 | 6 |
|11 | L | 27 | b | 43 | r | 59 | 7 |
|12 | M | 28 | c | 44 | s | 60 | 8 |
|13 | N | 29 | d | 45 | t | 61 | 9 |
|14 | O | 30 | e | 46 | u | 62 | + |
|15 | P | 31 | f | 47 | v | 63 | / |
需要注意的是上述base编码的索引表都是可以改变的。
base64换表的解密脚本:
import base64
str1 = "cPQebAcRp+n+ZeP+YePEWfP7bej4YefCYd/7cuP7WfcPb/URYeMRbesObi/=" # 待解密的base64编码
string1 = "LMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/ABCDEFGHIJK" #替换的表
string2 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"
print (base64.b64decode(str1.translate(str.maketrans(string1,string2))))
关于解码/加密:
1.使用cyberchef解密
2.使用base64自定义解码脚本
#s = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"
s = ""
def My_base64_decode(inputs):
# 将字符串转化为2进制
bin_str = []
for i in inputs:
if i != '=':
x = str(bin(s.index(i))).replace('0b', '')
bin_str.append('{:0>6}'.format(x))
#print(bin_str)
# 输出的字符串
outputs = ""
nums = inputs.count('=')
while bin_str:
temp_list = bin_str[:4]
temp_str = "".join(temp_list)
#print(temp_str)
# 补足8位字节
if(len(temp_str) % 8 != 0):
temp_str = temp_str[0:-1 * nums * 2]
# 将四个6字节的二进制转换为三个字符
for i in range(0,int(len(temp_str) / 8)):
outputs += chr(int(temp_str[i*8:(i+1)*8],2))
bin_str = bin_str[4:]
print("Decrypted String:\n%s "%outputs)
input_str = input("Please enter a string that needs to be decrypted: \n")
My_base64_decode(input_str)
base85编码
Base85编码,也称为ASCII85编码,是一种将二进制数据转换为ASCII字符的编码方法。它通常用于在文本协议中传输二进制数据,尤其在Adobe的PostScript和PDF文件格式中使用。
原理:
1、准备要编码的二进制数据: 将要编码的二进制数据准备好,通常是字节的形式。
2、分组: 将二进制数据分成固定大小的组,每组通常为4字节(32位)。
3、将每个组的二进制数据转换为整数: 将每个4字节的二进制数据视为一个32位的二进制整数,然后将它转换为一个十进制整数。这个整数的范围通常是0到4294967295(2^32-1)。
4、Base85编码: 将每个十进制整数编码为Base85字符。
------------------------------------------------------------------------------------
(一)Base85字符集通常包括85个字符,通常是ASCII字符集中的可打印字符,除去易混淆的字符和可能引起歧义的字符。
(二)以32位整数为例,将它分成5组,每组将被编码为5个Base85字符。
(三)每个5个字符的组对应一个32位整数,根据其在Base85字符集中的位置来选择。
(四)Base85编码的结果是一个文本字符串,其中包含一系列Base85字符,每5个字符分为一组,每组表示一个32位整数。
5、填充(可选): 如果原始数据的长度不是4字节的倍数,可以使用"z"字符作为填充字符,以确保编码长度是5的倍数。
---------------------------------------------------------------------------------------
Base91编码
Base91编码是一种将二进制数据转换为文本编码的方法,通常用于在文本协议中传输二进制数据。与Base64相比,Base91编码具有更高的数据密度,但编码后的文本相对较长。
原理:
1、准备要编码的二进制数据: 将要编码的二进制数据准备好,通常是字节的形式。
2、分组: 将二进制数据分成固定大小的组,每组通常为3字节(24位)。如果最后一组不足3字节,可以进行填充。
3、Base91编码: 将每个3字节的二进制数据编码为Base91字符。
---------------------------------------------------------------------------------------------
(一)Base91字符集通常包括91个字符,通常是可打印ASCII字符集中的字符,除去易混淆的字符和可能引起歧义的字符。
(二)以24位的二进制数据为例,将其分成4组,每组将被编码为4个Base91字符。
(三)每个4字符的组对应一个24位的整数,根据其在Base91字符集中的位置来选择。
(四)Base91编码的结果是一个文本字符串,其中包含一系列Base91字符,每4个字符分为一组,每组表示一个24位整数。
------------------------------------------------------------------------------------
4、填充(可选): 如果原始数据的长度不是3字节的倍数,可以使用一或多个填充字符来确保编码长度是4的倍数
Base100编码
base100是一种对称加密,加密后全是emoji表情。
Base100 是一种基于 Unicode 表情符号的编码方式,也称为 "Emoji Encoding"。它将二进制数据转换为一系列表情符号,通常用于娱乐或非正式场景。Base100 并非标准编码,但在某些社区(如程序员或社交媒体用户)中流行。
Base100 的工作原理:
---------------------------------------------------------------------------------------------------
Base100 将每 8 位(1 字节)的数据映射到一个特定的表情符号。编码表通常包含 256 个不同的表情符号,每个符号对应一个唯一的字节值(0-255)。编码过程直接将字节流转换为表情符号序列,解码则是反向操作。
-----------------------------------------------------------------------------------------
Base100 的特点:
可视化强:编码结果是一串表情符号,易于识别。
非标准性:不属于官方编码标准,兼容性有限。
低效:每个字节转换为一个 4 字节的 Unicode 表情符号,数据膨胀严重。
C语言的解码:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdint.h>
#include <stdbool.h>
// Base100字符集 - 256个Emoji表情(每个4字节UTF-8编码)
static const char* const BASE100_EMOJIS[256] = {
"🐀", "🐁", "🐂", "🐃", "🐄", "🐅", "🐆", "🐇", "🐈", "🐉", "🐊", "🐋", "🐌", "🐍", "🐎", "🐏",
"🐐", "🐑", "🐒", "🐓", "🐔", "🐕", "🐖", "🐗", "🐘", "🐙", "🐚", "🐛", "🐜", "🐝", "🐞", "🐟",
"🐠", "🐡", "🐢", "🐣", "🐤", "🐥", "🐦", "🐧", "🐨", "🐩", "🐪", "🐫", "🐬", "🐭", "🐮", "🐯",
"🐰", "🐱", "🐲", "🐳", "🐴", "🐵", "🐶", "🐷", "🐸", "🐹", "🐺", "🐻", "🐼", "🐽", "🐾", "🐿",
"👀", "👁", "👂", "👃", "👄", "👅", "👆", "👇", "👈", "👉", "👊", "👋", "👌", "👍", "👎", "👏",
"👐", "👑", "👒", "👓", "👔", "👕", "👖", "👗", "👘", "👙", "👚", "👛", "👜", "👝", "👞", "👟",
"👠", "👡", "👢", "👣", "👤", "👥", "👦", "👧", "👨", "👩", "👪", "👫", "👬", "👭", "👮", "👯",
"👰", "👱", "👲", "👳", "👴", "👵", "👶", "👷", "👸", "👹", "👺", "👻", "👼", "👽", "👾", "👿",
"💀"}#最后还缺一个,电脑打不出来
总结:
base家族编码都不算难,根据特征特点找到对应的加解密方式就可以了。下面总结一下各个base编码的特点。
base16特征:由大写字母(A-Z)和数字(0-9)组成,通常不需要“=”填充
base32特征:由大写字母(A-Z)和数字(2-7)组成,需要“=”填充
base64特征:大小写字母(a-Z)和数字(0-9)以及特殊字符('+','/')不满3的倍数用“=”补齐
base58特征:同base64相比,少了数字‘0’和字母‘O'数字’1‘和字母’I‘以及'+'和'/'符号,也没有“=”
base85特征:有很多奇怪的符号,但一般没有“=”
base91特征:由91个字符(0-9,a-z,A-Z,!#$%&()*+,./:;<=>?@[]^_`{|}~”)组成
base100特征:全是emoji表情。
一个很好用的网站:https://www.toolhelper.cn/EncodeDecode/Base64
献祭出个人的焚决,自动识别编码的程序:
#无Base58和Base100
import base64
import re
import base91
def baseDec(text, type):
if type == 1:
return base64.b16decode(text)
elif type == 2:
return base64.b32decode(text)
elif type == 3:
return base64.b64decode(text)
elif type == 4:
return base64.b85decode(text)
elif type == 5:
return base91.decode(text.decode())
else:
pass
def detect(text):
try:
if re.match("^[0-9A-F=]+$", text.decode()) is not None:
return 1
except:
pass
try:
if re.match("^[A-Z2-7=]+$", text.decode()) is not None:
return 2
except:
pass
try:
if re.match("^[A-Za-z0-9+/=]+$", text.decode()) is not None:
return 3
except:
pass
try:
if re.match("^[A-Za-z0-9$%()*+,-./:;?@[\]^_`{|}~]+$", text.decode()) is not None:
return 4
except:
pass
try:
if re.match("^[^-\']+$", text.decode()) is not None:
return 5
except:
pass
return 5
def autoDec(text):
floor = 0
while True:
try:
code = detect(text)
text = baseDec(text, code)
floor += 1
print("第{0}层:\n".format(floor), text)
if not text: break
except:
break
if __name__ == "__main__":
with open("secenc.txt",'rb') as f:
content = f.read()
# content = "60290f0225011a72697f420d1f4e402778231b".encode()
autoDec(content)
python实现Base64:(出自Sciurdae师傅)
"""
base64实现
"""
import base64
import string
# base 字符集
base64_charset = string.ascii_uppercase + string.ascii_lowercase + string.digits + '+/'
def encode(origin_bytes):
"""
将bytes类型编码为base64
:param origin_bytes:需要编码的bytes
:return:base64字符串
"""
# 将每一位bytes转换为二进制字符串
base64_bytes = ['{:0>8}'.format(str(bin(b)).replace('0b', '')) for b in origin_bytes]
resp = ''
nums = len(base64_bytes) // 3
remain = len(base64_bytes) % 3
integral_part = base64_bytes[0:3 * nums]
while integral_part:
# 取三个字节,以每6比特,转换为4个整数
tmp_unit = ''.join(integral_part[0:3])
tmp_unit = [int(tmp_unit[x: x + 6], 2) for x in [0, 6, 12, 18]]
# 取对应base64字符
resp += ''.join([base64_charset[i] for i in tmp_unit])
integral_part = integral_part[3:]
if remain:
# 补齐三个字节,每个字节补充 0000 0000
remain_part = ''.join(base64_bytes[3 * nums:]) + (3 - remain) * '0' * 8
# 取三个字节,以每6比特,转换为4个整数
# 剩余1字节可构造2个base64字符,补充==;剩余2字节可构造3个base64字符,补充=
tmp_unit = [int(remain_part[x: x + 6], 2) for x in [0, 6, 12, 18]][:remain + 1]
resp += ''.join([base64_charset[i] for i in tmp_unit]) + (3 - remain) * '='
return resp
def decode(base64_str):
"""
解码base64字符串
:param base64_str:base64字符串
:return:解码后的bytearray;若入参不是合法base64字符串,返回空bytearray
"""
if not valid_base64_str(base64_str):
return bytearray()
# 对每一个base64字符取下标索引,并转换为6为二进制字符串
base64_bytes = ['{:0>6}'.format(str(bin(base64_charset.index(s))).replace('0b', '')) for s in base64_str if
s != '=']
resp = bytearray()
nums = len(base64_bytes) // 4
remain = len(base64_bytes) % 4
integral_part = base64_bytes[0:4 * nums]
while integral_part:
# 取4个6位base64字符,作为3个字节
tmp_unit = ''.join(integral_part[0:4])
tmp_unit = [int(tmp_unit[x: x + 8], 2) for x in [0, 8, 16]]
for i in tmp_unit:
resp.append(i)
integral_part = integral_part[4:]
if remain:
remain_part = ''.join(base64_bytes[nums * 4:])
tmp_unit = [int(remain_part[i * 8:(i + 1) * 8], 2) for i in range(remain - 1)]
for i in tmp_unit:
resp.append(i)
return resp
def valid_base64_str(b_str):
"""
验证是否为合法base64字符串
:param b_str: 待验证的base64字符串
:return:是否合法
"""
if len(b_str) % 4:
return False
for m in b_str:
if m not in base64_charset:
return False
return True
if __name__ == '__main__':
s = '都看到这里了可以点个关注吗'.encode()
local_base64 = encode(s)
print('使用本地base64加密:', local_base64)
b_base64 = base64.b64encode(s)
print('使用base64加密:', b_base64.decode())
print('使用本地base64解密:', decode(local_base64).decode())
print('使用base64解密:', base64.b64decode(b_base64).decode())
a = ''.encode()
b = base64.b64decode(a).decode()
print(b)

Comments 1 条评论
出自Sciurdae师傅指导