关于在线Base64编码不一致的问题研究

摘要:近来进行 base64 编码编程的时候发现,很多在线网站编码出的 base64 字符串不一致,于是进行了简单的尝试发现了不一样的原因在于换行的处理。

换行的问题

  1. 在 Windows 系统下,换行是 \r\n
  2. 在 Linux 和 Unix 系统下 (包括新版的 Mac OS),换行是 \n
  3. 在旧版的 Mac OS 系统下换行是 \r

其中 \r 可以称为 Carriage Return,简称为 CR。另外 \n 称为 Line Feed,简称为 LF

大家可以参考该问答

They are used to mark a line break in a text file. As you indicated, Windows uses two characters the CR LF sequence; Unix only uses LF and the old MacOS ( pre-OSX MacIntosh) used CR.

Base64对换行的处理

所以 Base64 字符串出现不同的原因在于不同系统对于换行的处理,如果是基于 Windows 系统的,那么换行就会被当做 \r\n 来处理,但是如果是 Linux 或 Mac OS X 将会仅仅认为换行为 \n

  1. \r ASCII00001101
  2. \n ASCII00001010

所以当发现在线工具或者自己转化的时候出现不一致,可以知道这个不一致就因为在 Windows 系统上字符串(带有换行符)会多出一个 \r,另外我们知道一旦多一个字符,就会导致后面的编码全部不一致了。

编码经验

假设我们现在有一个包含换行符的字符串:

1
S1\n

其中 length(S1) 表示 S 字符串的长度,我们知道在 ASCII 编码每个字符 8 bits,2个字节。而 base64 编码每个字符是 6个 bits,1.5个字节。所以 S 个字符串将会转化base64字符串长度为

Linux

1
(length(S1)+1)* 8 / 6

Windows

1
(length(S1)+2)* 8 / 6

那么对于 Windows 的转化,由于换行符固定而且有两个,所以我们能不能根据换行符之前的字符数量来判断换行符转化的 base64 字符呢?

那么假设

1
t = (length(S1) MOD 3

换行符最后一个字符为 #

且其二进制 ASCII 码为 aa bb cc dd

t = 0

那么 base64 最后的 \r\n 将转换为

1
2
3
4
\r          \n
00 00 11 01 00 00 10 10 XX
3 16
D Q

t = 1

那么 base64 最后的 \r\n 将转换为

1
2
3
4
   \r          \n
dd 00 00 11 01 00 00 10 10
-- -- -- 52 10
0 K

t = 2

那么 base64 最后的 \r\n 将转换为

1
2
3
4
      \r          \n
cc dd 00 00 11 01 00 00 10 10
-- -- -- 13 2
N C

所以如果转化的 base64 在第一行换行字符串左右包含如上三种字符,表示该系统肯定为 windows,把换行当作 \r\n

另附 Base64 字符对应表

Value Char Value Char Value Char Value Char
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 /

另附 ASCII 字符对应表

ASCII值 控制字符 ASCII值 控制字符 ASCII值 控制字符 ASCII值 控制字符
0 NUT 32 (space) 64 @ 96
1 SOH 33 ! 65 A 97 a
2 STX 34 66 B 98 b
3 ETX 35 # 67 C 99 c
4 EOT 36 $ 68 D 100 d
5 ENQ 37 % 69 E 101 e
6 ACK 38 & 70 F 102 f
7 BEL 39 , 71 G 103 g
8 BS 40 ( 72 H 104 h
9 HT 41 ) 73 I 105 i
10 LF 42 * 74 J 106 j
11 VT 43 + 75 K 107 k
12 FF 44 , 76 L 108 l
13 CR 45 - 77 M 109 m
14 SO 46 . 78 N 110 n
15 SI 47 / 79 O 111 o
16 DLE 48 0 80 P 112 p
17 DCI 49 1 81 Q 113 q
18 DC2 50 2 82 R 114 r
19 DC3 51 3 83 S 115 s
20 DC4 52 4 84 T 116 t
21 NAK 53 5 85 U 117 u
22 SYN 54 6 86 V 118 v
23 TB 55 7 87 W 119 w
24 CAN 56 8 88 X 120 x
25 EM 57 9 89 Y 121 y
26 SUB 58 : 90 Z 122 z
27 ESC 59 ; 91 [ 123 {
28 FS 60 < 92 / 124
29 GS 61 = 93 ] 125 }
30 RS 62 > 94 ^ 126 `
31 US 63 ? 95 _ 127 DEL