我正在阅读这个libb64源代码,用于编码和解码base64数据。
我知道编码过程,但我无法弄清楚如何构造以下解码表以便快速查找以执行编码的base64字符的解码。这是他们正在使用的表格:
static const char decoding[] = {62,-1,-1,-1,63,52,53,54,55,56,57,58,59,60,61,-1,-1,-1,-2,-1,-1,-1,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,-1,-1,-1,-1,-1,-1,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51};
有人可以解释一下这个表中的值如何用于解码目的。
答案 0 :(得分:5)
这是一个移位且有限的ASCII翻译表。表的键是ASCII值,值是base64解码值。该表被移位,使得索引0
实际映射到ASCII字符+
,并且任何其他索引在+
之后映射ASCII值。表中的第一个条目ASCII字符+
映射到base64值62
。然后忽略三个字符(ASCII ,-.
),并将下一个字符映射到base64值63
。下一个字符是ASCII /
。
如果您查看该表和ASCII table。
,其余部分将变得明显它的用法是这样的:
int decode_base64(char ch) {
if (ch < `+` or ch > `z`) {
return SOME_INVALID_CH_ERROR;
}
/* shift range into decoding table range */
ch -= `+`;
int base64_val = decoding[ch];
if (base64_val < 0) {
return SOME_INVALID_CH_ERROR;
}
return base64_val;
}
答案 1 :(得分:5)
众所周知,每个字节有8位,可能有256个组合,带有2个符号(base2)
使用2个符号需要浪费8个字符来表示一个字节,例如'01010011'
使用base 64可以表示64个组合,其中包含1个char ...
所以,我们有一个基表:
A = 000000
B = 000001
C = 000010
...
如果您有单词'Man',那么您有字节:
01001101,01100001,01101110
所以流:
011010110000101101110
中断六位组:010011 010110 000101 101110
010011 = T
010110 = W
000101 = F
101110 = u
所以,'男人'=&gt; base64编码='TWFu'。
如图所示,这对于长度为6的长度的流是完美的
如果您的流不是6的倍数,例如'Ma',您就拥有了流:
010011 010110 0001
你需要完成6人组:
010011 010110 000100
所以你有编码基数64:
010011 = T
010110 = W
000100 = E
所以,'Ma'=&gt; 'TWE'
在解码流之后,在这种情况下,您需要将最后一个多个长度计算为8的倍数,因此删除额外的位以获取原始流:
T = 010011
W = 010110
E = 000100
1)010011 010110 000100
2)01001101 01100001 00
3)01001101 01100001 ='Ma'
实际上,当我们设置尾随的00时,我们用'='标记Base64字符串的结尾到每个尾随'00添加('Ma'==&gt; Base64'TWE =')
另见链接:http://www.base64decode.org/
在基础64上表示的图像是用许多应用程序中的字符串表示的好选项,其中难以直接使用真实二进制流。真正的二进制流更好,因为它是一个base256,但在HTML中很难,例如,有两种方式,轻微流量,或更容易使用字符串。
也参见ASCII码,base 64的字符在表ASCII上从范围'+'到'z'但是'+'和'z'之间有一些不是64位符号的值
'+'= ASCII DEC 43
...
'z'= ASCII DEC 122
从DEC 43到122是80值但是
43 OK ='+'
44不是基本64个符号,因此解码索引是-1(无效符号到base64)
45 ....
46 ...
...
122 OK ='z'
做解码所需的char,将43('+')递减为vector上的索引0,以便通过索引快速访问,解码[80] = {62,-1,-1 ........, 49,50,51};
罗伯托诺瓦科斯基
开发者系统
答案 2 :(得分:0)
考虑这两个映射表:
static const char decodingTab[] = {62,-1,-1,-1,63,52,53,54,55,56,57,58,59,60,61,-1,-1,-1,-2,-1,-1,-1,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,-1,-1,-1,-1,-1,-1,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51};
static unsigned char encodingTab[64]="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
decodingTab是encondingTab的反向映射表。 因此,decodingTab [i]永远不应为-1。 实际上,仅期望64个值。但是encodingTab的大小是128。 因此,在解码表中,意外索引值设置为-1(不在[0,63]中的任意数字)
char c;
unsigned char i;
...
encoding[decoding[c]]=c;
decoding[encoding[i]=i;
希望有帮助。