Base64编码原理与实现

xiaoxiao2026-08-03  7

本文为原创,如需转载,请注明作者和出处,谢谢! Base64编码的原理是按bit将每6个bit转换成Base64编码表中的相应字符。下面是Base64的编码表: 0 A 17 R 34 i 51 z 1 B 18 S 35 j 52 0 2 C 19 T 36 k 53 1 3 D 20 U 37 l 54 2 4 E 21 V 38 m 55 3 5 F 22 W 39 n 56 4 6 G 23 X 40 o 57 5 7 H 24 Y 41 p 58 6 8 I 25 Z 42 q 59 7 9 J 26 a 43 r 60 8 10 K 27 b 44 s 61 9 11 L 28 c 45 t 62 + 12 M 29 d 46 u 63 / 13 N 30 e 47 v 14 O 31 f 48 w 15 P 32 g 49 x 16 Q 33 h 50 y 在转换到最后一个字节时,可能出现如下两种情况: 1. 最后只剩下2个bit。 2. 最后只剩下4个bit。 对于这两种情况,需要在后面被0,如下面的两个字节: <!--<br /> <br /> Code highlighting produced by Actipro CodeHighlighter (freeware)<br /> http://www.CodeHighlighter.com/<br /> <br /> --> 11011001 11011101 在转换上面的字节时,最后会剩下4个bit。也就是1101,这时需要在后面补0,也就是变成了110100。如果后面补一对0,转换结果后面加一个“=”,如果补两对0,加两个“=”,也就是总共的bit数除3的余数为1,则加一个“=”,余数为2,加两个“=”。上面的两个字节是16个bit,除3的余数是1,因此,需要补一个“=”,也就是将这两个字节分成如下三组: <!--<br /> <br /> Code highlighting produced by Actipro CodeHighlighter (freeware)<br /> http://www.CodeHighlighter.com/<br /> <br /> --> 110110 011101 110100 其中110100后面两个0是补的,因此,查找上面的base64编码表可将这两个字节转换成如下的Base64编码: <!--<br /> <br /> Code highlighting produced by Actipro CodeHighlighter (freeware)<br /> http://www.CodeHighlighter.com/<br /> <br /> --> 2d0 = 下面我们来实现这个算法。算法的基本原理如下: 由于每次转换都需要6个bit,而这6个bit可能都来自一个字节,也可以来自前后相临的两个字节。定义两个变量:prevByteBitCount和nextByteBitCount,这两个变量分别表述从前一个和后一个节字取得的bit数。如果prevByteBitCount为0,表示6个bit全部来自下一个字节的高6位。如果nextByteBitCount = 0,表示6个bit全部来自前一个字节的低6位。最后通过适当的移位获得所需要的6个bit,再在上面的base64编码表中查找相应的字符。算法的实现代码如下: <!--<br /> <br /> Code highlighting produced by Actipro CodeHighlighter (freeware)<br /> http://www.CodeHighlighter.com/<br /> <br /> --> public static Stringencoder( byte []bytes) { StringBuilderresult = new StringBuilder(); Stringbase64 = " ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/ " ; // prevByteBitCount表示从前一个字节取得的bit数,nextByteBitCount表示从后一个字节取得的bit数 int prevByteBitCount = 0 ,nextByteBitCount = 6 ; // i表示当前的数组索引,n表示已经处理的位数 int i = 0 ,n = 0 ; // byteCount表示总的位数 int byteCount = 8 * bytes.length; byte b = 0 ; while ( true ) { // 处理从前后两个字节取得位数的情况 if (prevByteBitCount > 0 && nextByteBitCount > 0 ) { // 将前一个字节的低位向左移nextByteBitCount个bit,并使下一个字节的高位(nextByteBitCount指定的位数)右移到字节的最低位, // 然后将两个位移结果进行逻辑或,也就是将从前一个字节和后一个字节取得的相应的bit合并为一个字节的低位 b = ( byte )((( 0xff & bytes[i]) << nextByteBitCount) | (( 0xff & bytes[i + 1 ]) >> ( 8 - nextByteBitCount))); // 将逻辑或后的结果的最高两个bit置成0 b = ( byte )(b & 0x3f ); prevByteBitCount = 8 - nextByteBitCount; nextByteBitCount = 6 - prevByteBitCount; } // 处理从后一个字节取得高6位的情况 else if (prevByteBitCount == 0 ) { // 后一个字节的高6位右移动低6位 b = ( byte )(( 0xff & bytes[i]) >> ( 8 - nextByteBitCount)); // 处理后面的位时,就是从前一个字节取2个bit,从后一个字字取4个bit prevByteBitCount = 2 ; nextByteBitCount = 4 ; } // 处理从前一个字节取得低6位的情况 else if (nextByteBitCount == 0 ) { // 将前一个字节的最高两个bit置成0 b = ( byte )( 0x3f & bytes[i]); // 处理后面的位时,从后一个字节取6个bit prevByteBitCount = 0 ; nextByteBitCount = 6 ; } result.append(base64.charAt(b)); n += 6 ; i = n / 8 ; int remainBitCount = byteCount - n; if (remainBitCount < 6 ) { // 将剩余的bit补0后,仍然需要在base64编码表中查找相应的字符,并添加到结果字符串的最后 if (remainBitCount > 0 ) { b = bytes[bytes.length - 1 ]; b = ( byte )( 0x3f & (b << ( 6 - remainBitCount))); result.append(base64.charAt(b)); } break ; } } // 如果总bit数除3的余数为1,加一个“=”,为2,加两个“=” n = byteCount % 3 ; for (i = 0 ;i < n;i ++ ) result.append( " = " ); return result.toString(); } 最后可以使用下面的代码来验证encoder方法的正确性: <!--<br /> <br /> Code highlighting produced by Actipro CodeHighlighter (freeware)<br /> http://www.CodeHighlighter.com/<br /> <br /> --> Strings = " 中华人民共和国 " ; byte []bytes = s.getBytes( " UTF-8 " ); System.out.println(encoder(bytes)); // 使用jdk提供的base64转换类对字节数组进行base64编码 sun.misc.BASE64Encoderbase64Encoder = new sun.misc.BASE64Encoder(); System.out.println(base64Encoder.encode(bytes)); 上面的代码的执行结果如下: <!--<br /> <br /> Code highlighting produced by Actipro CodeHighlighter (freeware)<br /> http://www.CodeHighlighter.com/<br /> <br /> --> 5Lit5Y2O5Lq65rCR5YWx5ZKM5Zu9 5Lit5Y2O5Lq65rCR5YWx5ZKM5Zu9 国内最棒的Google Android技术社区(eoeandroid),欢迎访问! 《银河系列原创教程》发布 《Java Web开发速学宝典》出版,欢迎定购
转载请注明原文地址: https://www.6miu.com/read-5050613.html

最新回复(0)