编码

Base系列编码浅析

Base编码有很多种,常用****的有:

base16 base32 base64 base85 base36 base 58 base91 base 92 base62


Base16

  • 使用16个ASCII可打印字符**(数字0-9和字母A-F)**,对任意字节数据进行编码。
  • 先获取输入字符串每个字节的二进制值(不足8比特在高位补0),然后将其串联进来,再按照4比特一组进行切分,将每组二进制数分别转换成十进制。
  • Base16编码后的数据量是原数据的两倍:1000比特数据需要250个字符(即 250*8=2000 比特)。

:可以看到8比特数据按照4比特切分刚好是两组,所以Base16不可能用到填充符号“=”。

换句话说:Base16使用两个ASCII字符去编码原数据中的一个字节数据。

Base16编码是一个标准的十六进制字符串(注意是字符串而不是数值),更易被人类和计算机使用,因为它并不包含任何控制字符,以及Base64和Base32中的“=”符号。


Base32

  • Base32编码是使用32个可打印字符(字母A-Z和数字2-7)对任意字节数据进行编码的方案,编码后的字符串不用区分大小写并排除了容易混淆的字符,可以方便地由人类使用并由计算机处理。
  • Base32主要用于编码二进制数据,但是Base32也能够编码诸如ASCII之类的二进制文本。
  • Base32将任意字符串按照字节进行切分,并将每个字节对应的二进制值(不足8比特高位补0)串联起来,按照5比特一组进行切分,并将每组二进制值转换成十进制来对应32个可打印字符中的一个。

由于数据的二进制传输是按照8比特一组进行(即一个字节),因此Base32按5比特切分的二进制数据必须是40比特的倍数(5和8的最小公倍数)。

例如输入单字节字符“%”,它对应的二进制值是“100101”,前面补两个0变成“00100101”(二进制值不足8比特的都要在高位加0直到8比特),从左侧开始按照5比特切分成两组:“00100”和“101”,后一组不足5比特,则在末尾填充0直到5比特,变成“00100”和“10100”,这两组二进制数分别转换成十进制数,通过上述表格即可找到其对应的可打印字符“E”和“U”,但是这里只用到两组共10比特,还差30比特达到40比特,按照5比特一组还需6组,则在末尾填充6个“=”。填充“=”符号的作用是方便一些程序的标准化运行,大多数情况下不添加也无关紧要,而且,在URL中使用时必须去掉“=”符号。


Base64

  • Base64是一种基于64个可打印字符来表示二进制数据的表示方法。由于,所以每6个比特为一个单元,对应某个可打印字符。3个字节有24个比特,对应于4个Base64单元,即3个字节可由4个可打印字符来表示。
  • 在Base64中的可打印字符包括字母A-Z、a-z、数字0-9,这样共有62个字符,此外两个可打印符号在不同的系统中而不同。一些如uuencode的其他编码方法。
  • 它可用来作为电子邮件的传输编码。
  • Base64常用于在通常处理文本数据的场合,表示、传输、存储一些二进制数据,包括MIME的电子邮件及XML的一些复杂数据。

注:BinHex的版本使用不同的64字符集来代表6个二进制数字,但是不被称为Base64。

如果要编码的字节数不能被3整除,最后会多出1个或2个字节,那么可以使用下面的方法进行处理:

(1)先使用0字节值在末尾补足,使其能够被3整除,然后再进行Base64的编码。

(2)在编码后的Base64文本后加上一个或两个=号,代表补足的字节数。

也就是说:

当最后剩余两个八位(待补足)字节(2个byte)时,最后一个6位的Base64字节块有四位是0值,最后附加上两个等号;

如果最后剩余一个八位(待补足)字节(1个byte)时,最后一个6位的base字节块有两位是0值,最后附加一个等号。

参考下表:


Base85

  • base85 也称为Ascii85,是Paul E. Rutter为btoa实用程序开发的一种二进制文本编码形式。通过使用五个ASCII字符来表示四个字节的二进制数据(使编码量1 / 4比原来大,假设每ASCII字符8个比特),它比更有效UUENCODE或Base64的,它使用四个字符来表示三个字节的数据(1 / 3的增加,假设每ASCII字符8个比特)。
  • 用途是Adobe的PostScript和Portable Document Format文件格式,以及Git使用的二进制文件的补丁编码。
  • 与Base64一样,Base85编码的目标是对二进制数据可打印的ASCII字符进行编码。但是它使用了更大的字符集,因此效率更高一些。具体来说,它可以用5个字符编码4个字节(32位)。

摘自wiki介绍的一个例子:


Base36

Base36是一个二进制到文本编码表示方案的二进制数据以ASCII通过将其转化为一个字符串格式基数 -36表示。选择36十分方便,因为可以使用阿拉伯数字 0–9和拉丁字母 A–Z [1](ISO基本拉丁字母)表示数字。

每个base36位需要少于6位的信息来表示。

摘自wiki的一个例子:

有符号的32位和64位整数分别最多只能容纳6个或13个base-36位数字(许多base-36位数字可能会使32位和64位整数溢出)。

例如,在base-36中,“ 922337203685477575807 ” 的64位带符号整数最大值为“ 1Y2P0IJ32E8E7 ”。

类似地,在base-36中,“ 2147483647 ” 的32位带符号整数最大值为“ ZIK0ZJ ”。

(这里没看太懂是怎么转换的,请大佬指教~)

用于从BASE10编码BASE36的Python代码

1
2
3
4
5
6
7
8
9
10
11
12
def base36encode(integer): 
chars = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ'

sign = '-' if integer < 0 else ''
integer = abs(integer)
result = ''

while integer > 0:
integer, remainder = divmod(integer, 36)
result = chars[remainder]+result

return sign+result


Base58

  • Base58是用于Bitcoin中使用的一种独特的编码方式,主要用于产生Bitcoin的钱包地址。
  • 相比Base64,Base58不使用数字”0”,字母大写”O”,字母大写”I”,和字母小写”l”,以及”+”和”/“符号

设计Base58主要的目的是:

  1. 避免混淆。在某些字体下,数字0和字母大写O,以及字母大写I和字母小写l会非常相似。
  2. 不使用”+”和”/“的原因是非字母或数字的字符串作为帐号较难被接受。
  3. 没有标点符号,通常不会被从中间分行。
  4. 大部分的软件支持双击选择整个字符串。


Base91

顾名思义,basE91需要91个字符来表示ASCII编码的二进制数据。 从94个可打印ASCII字符(0x21-0x7E)中,以下三个字符被省略以构建basE91字母:

-(破折号,0x2D)

\(反斜杠,0x5C)

‘(撇号,0x27)

  • basE91是将二进制数据编码为ASCII字符的高级方法。
  • 它类似于UUencode或base64,但效率更高。 basE91产生的开销取决于输入数据。 它的数量最多为23%(而base64为33%),范围可以降低到14%,通常发生在0字节块上。
  • 这使得basE91对于通过二进制不安全连接(例如电子邮件或终端线)传输较大的文件非常有用。

转换表由其余字符组成,如下所示。


Base92

有关Base92的资料实在是很少,但是笔者找到了这一篇博客:

https://thenoviceoof.com/blog/projects/base92/

以下介绍均摘自这篇博客

“ 如果您对将二进制信息从一个地方转移到另一地方一无所知,那么就知道将数据从一个地方转移到另一地方 可能很危险。就是说,这对您的数据有害:也许您需要在仅用于ASCII文本的通道上传输Blob ,并且所有’\n’以C样式字符串表示的字节都会突然有一个同级符号’\r’。或者,您的传输层实际上真的真的是以null终止的字符串,并且您恰好在字节边界上连续有8个连续的0位,即使它位于blob中一个32位整数的中间,并且你结束了只有一半您的数据。

解决此问题的一种方法是使用base64,它使用所有数字和大写/小写字母字符对数据进行编码(再加上两个,但现在我们将忽略它们)。现在,您在传输层上尝试解释您的字节时没有任何问题,因为每个人都可以很好地处理字母数字字符,如果没有,您可能不想使用它们。

当然,使用base64了一段时间后,您可能会注意到,虽然您不会因为一位反复无常的上帝以为他在提供帮助,却没有按照自己的意愿对数据进行更改,但您却通过使用放弃了效率base64。对于二进制blob中的每3个字节,如果需要传输字母数字字符,则有4个字节,因此您要以33%的容量税来支付数据保护费用:如果暴徒可以在保护球拍中掠走33%,相信他们会的。

看一下base64,您可能会注意到,除了可以使用的64个字符外,还有更多可显示的ASCII字符,base64可以在编码中使用这些字符以提高传输密度。这样就base85诞生了,使用了……您猜对了,有85个字符!这次,将4字节的二进制数据编码为5个ASCII字符,这将导致20%的传输大小开销。但你能做什么呢?好像没有更多可显示的ASCII了……哦,等等。

所以似乎没有人试图超越明显的下一步base85,所以我决定尝试自己做base92。

在键入编码的字符串时,`和“与普通引号’太相似,以使其舒适。希望在区分l / 1和0 / O时使用的字体好。但是,我们将〜用作特殊符号(空字符串)。有94个可打印的ascii字符,因此我们最终得到91个字符,或每个字符6.5位。一旦包含〜,则将有92个字符:因此,为base92。(老实说,base91的名字太丑陋了,无法处理)

一旦每个字符有6.5位,则可以一次使用13位,并使用类似于base85的除法和取模方案,用它们产生两个输出字符。这可能意味着,与base92编码相比,它更能抵抗损坏,因为任何损坏都更加局限(一位更改仅影响2-3个字节,而不影响4个字节)。

注意:在某些需要某些输出的情况下,可能需要将〜用作空字符串分号:但是,传递空字符串进行解码不会导致它变成barf,因此不要求使用〜。

旁注:以前base92产生的输出的长度与输入的长度非单调增长。这已不再是这种情况。

另一个旁注:base64和base85更加优雅,将一个较小的字节整数干净地映射到另一个较小的字节整数。base92将13个字节映射为16个字符,从大小的角度来看,这比base85的4至5个字符更好,但是相当不雅观。我们还遵循使用高除数乘积作为第一个字节的base85约定。”

以上是笔者用谷歌翻译直接搬运的,如有描述不懂的小伙伴,请参照原文链接进行参考~


Base62

  • Base62编码将数字转换为ASCII字符串(0-9,az和AZ),反之亦然,这通常会导致字符串较短。

26个小写字母+26个大写字母+10个数字=62

(1)62进制与10进制的互相转化

  • 62进制转10进制与2进制转10进制相似。

2进制转10进制过程为: 从右到左用二进制的每个数去乘以2的相应次方,次方要从0开始。

62进制转10进制也类似,从右往左每个数*62的N次方,N从0开始。

那么,10进制转62进制也与10进制转2进制类似。 即:不断除以62取余数,然后倒序。

(2)关于短Url的转换

主要思路,维护一个全局自增的id,每来一个长url,将其与一个自增id绑定,然后利用base62将该自增id转换为base62字符串,即完成转换。

以上就是对Base系列编码的浅析,部分知识是笔者从wiki上搬运过来的,也参考了很多博客文章和资料。如有错误及不足之处,请大佬们多提建议~

参考资料:

https://en.wikipedia.org/wiki

https://blog.csdn.net/n0nameforn0w/article/details/87124053

https://thenoviceoof.com/blog/projects/base92/

https://segmentfault.com/a/1190000010516708


base16、32、64、85(较大的base)

base2048

![[Pasted image 20250322214036.png]]

例题

base64->base85(不断尝试大的base解密)

先进行htlm解密再进行base85解密

莫斯密码(-和.构成)

– ..- –.. .. -.- .. … –. —– —– -..

栅栏密码

分为标准型和W型

培根密码(只由A、B构成)

只由A、B构成

1、培根密码(Bacon’s cipher),本质上是一种替换密码,根据对应转换规则进行加密解密,通过不明显的特征来隐藏明文信息;
2、培根密码加密规则,将明文中的每个字母,转换成一组五个英文字母,即可得到密文,转换规则表如下:
a AAAAA g AABBA n ABBAA t BAABA
b AAAAB h AABBB o ABBAB u-v BAABB
c AAABA i-j ABAAA p ABBBA w BABAA
d AAABB k ABAAB q ABBBB x BABAB
e AABAA l ABABA r BAAAA y BABBA
f AABAB m ABABB s BAAAB z BABBB
3、培根密码解密时,将密文进行5个字符分组,替换成对应的明文即可。
4、培根密码,通常有两种不同的转换规则,一种为即I与J、U与V使用相同的编码,一种为I与J、U与V都使用不同编码。

html解密

md5解密

二维码解码器

把?后面的复制下来,进行base64解密

兔子解密(rot5、13、18、47)

新佛曰

新约佛论禅/佛曰加密 - 萌研社 - PcMoe!

Cimbar

https://www.bilibili.com/opus/975102170591395840

每个符号在哈希空间内与其他符号相隔至少 20 位,这确保了即使图像模糊或受到其他干扰时,也能清晰区分各个符号。

例题

SYC

对着图片敲二进制就行

0101 0011 0101 1001 0100 0011 0111 1011

0100 0001 0110 1110 0011 0000 0111 0100

0110 1000 0011 0011 0111 0010 0101 1111

0100 0001 0110 1101 0100 0000 0111 1010

0011 0001 0110 1110 0011 1001 0101 1111

0101 0001 0101 0010 0101 1111 0100 0011

0110 1111 0011 0100 0110 0101 0111 1101

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
# 给定的二进制数据
binary_data = """
01010011010110010100001101111011
01000001011011100011000001110100
01101000001100110111001001011111
01000001011011010100000001111010
00110001011011100011100101011111
01010001010100100101111101000011
01101111001101000110010101111101
"""

# 将所有二进制数据合并为一个字符串
binary_data = binary_data.replace(" ", "").replace("\n", "")

# 将每 8 位转换为一个字符
text = ""
for i in range(0, len(binary_data), 8):
byte = binary_data[i:i+8]
char = chr(int(byte, 2)) # 将 8 位二进制转换为整数,再转换为字符
text += char

# 输出结果
print("转换后的字符是:")
print(text)

ook编码

Brainfuck/Ook! Obfuscation/Encoding [splitbrain.org]

….. ….. ….! ?!!.? ….. ….. ….? .?!.? ….! .?… ….. …..

..!?! !.?.. ….. ….. ..?.? !.?.. ….. ….. ….. ….. !.?.. …..

….. .!?!! .?!!! !!!!! !!!!? .?!.? !!!!! !!!!! !!!!! .?… ….! ?!!.?

!!!!! !?.?! .?!!! !!!!! !!!!! .!!!. ?…. ….. ….. .!?!! .?… …..

….. .?.?! .?!.? .

url编码

url中的特殊符号及特殊字符编码对照表_空字符url编码-CSDN博客

HTML URL 编码参考手册 (w3school.com.cn)

1
2
3
4
5
6
7
8
9
10
11
12
有些符号在URL中是不能直接传递的,如果要在URL中传递这些特殊符号,那么就要使用他们的编码了。
编码的格式为:%加字符的ASCII码,即一个百分号%,后面跟对应字符的ASCII16进制)码值。例如 空格的编码值是"%20"
如果不使用转义字符,这些编码就会当URL中定义的特殊字符处理。
下表中列出了一些URL特殊符号及编码 十六进制值
1) + URL+号表示空格 %2B
2) 空格 URL中的空格可以用+号或者编码 %20
3) / 分隔目录和子目录 %2F
4) ? 分隔实际的 URL 和参数 %3F
5) % 指定特殊字符 %25
6) # 表示书签 %23
7) &amp; URL 中指定的参数间的分隔符 %26
8) = URL 中指定参数的值 %3D

编码
http://example.com/2023/11/10/编码/
Author
chaye
Posted on
November 10, 2023
Licensed under