所以我试图更好地理解base64编码,并且我在维基百科上看到了这个实现
private static String base64Encode(byte[] in) {
StringBuffer out = new StringBuffer((in.length * 4) / 3);
int b;
for (int i = 0; i < in.length; i += 3) {
b = (in[i] & 0xFC) >> 2;
out.append(codes.charAt(b));
b = (in[i] & 0x03) << 4;
if (i + 1 < in.length) {
b |= (in[i + 1] & 0xF0) >> 4;
out.append(codes.charAt(b));
b = (in[i + 1] & 0x0F) << 2;
if (i + 2 < in.length) {
b |= (in[i + 2] & 0xC0) >> 6;
out.append(codes.charAt(b));
b = in[i + 2] & 0x3F;
out.append(codes.charAt(b));
} else {
out.append(codes.charAt(b));
out.append('=');
}
} else {
out.append(codes.charAt(b));
out.append("==");
}
}
return out.toString();
}
我正在跟进,我走到了界限:
b = (in[i] & 0xFC) >> 2;
我不明白......为什么你会bitwise
和252
给一个数字然后转移它right 2
...如果你不是一样的话只是移动字节本身而不进行按位操作?例如:
b = in[i] >> 2;
说我的in[i]
是letter e
...代表101
或binary 01100101
。如果我向右移动2,我会得到011001
或25
。如果我按位&amp;我得到了
01100101
11111100
--------
01100100
然而转移将会切断最后的2 ...所以为什么还要这么做呢?
请有人为我澄清。感谢。
答案 0 :(得分:4)
IN in[i] >> 2
,in[i]
首先转换为int
。如果它是一个负字节(高位设置),它将被转换为负int(同时设置现在最高的24位)。
在(in[i] & 0xFC) >> 2
中,in[i]
如上所述转换为int
,然后& 0xFC
确保额外位全部重置为0.
你部分正确,因为(in[i] & 0xFF) >> 2
会给出相同的结果。 & 0xFF
是将字节转换为0到255范围内的非负int
的常用方法。
确定原始开发人员使用0xFC
而不是0xFF
的原因的唯一方法是询问他们 - 但我推测它可以更明显地使用哪些位正在使用。