欢迎拍砖~

在数据二进制和byte互相转换的地方方法写得有点挫,不知道有没有更好的方法~

顺便复习了java的一些基础东西,如位操作,原码反码补码

可以在这篇blog里学习到详细的知识点:http://www.cnblogs.com/zhangziqiu/archive/2011/03/30/ComputerCode.html

直接上代码吧,知识点在注释上

编码器:

  1 package jdbc.pro.lin;
  2 
  3 import java.util.HashMap;
  4 import java.util.Map;
  5 
  6 public class MyBase64Encoder {
  7 
  8     private static final Map<Integer, Character> INDEX_MAP = new HashMap<Integer, Character>();
  9 
 10     private static final char PADDING_CHAR = '=';
 11     static {
 12         int index = 0;
 13         for (int i = 0; i <= 25; i++) {
 14             INDEX_MAP.put(index, (char) ((int) 'A' + i));
 15             index++;
 16         }
 17 
 18         for (int j = 0; j <= 25; j++) {
 19             INDEX_MAP.put(index, (char) ((int) 'a' + j));
 20             index++;
 21         }
 22 
 23         for (int k = 0; k <= 9; k++) {
 24             INDEX_MAP.put(index, (char) ((int) '0' + k));
 25             index++;
 26         }
 27 
 28         INDEX_MAP.put(index, '+');
 29         index++;
 30         INDEX_MAP.put(index, '/');
 31     }
 32 
 33     public static String encode(byte[] bytes) throws Exception {
 34         /**
 35          * 1.转成二进制的字符串(长度为6的倍数)
 36          * 2.获取转义后的字符串 
 37          * 3.不是4的位数,填充=号
 38          */
 39         String binaryString = convertByteArray2BinaryString(bytes);
 40         String escapeString = escapeBinaryString(binaryString);
 41         return paddingEscapeString(escapeString);
 42     }
 43 
 44     private static String convertByteArray2BinaryString(byte[] bytes) {
 45 
 46         StringBuilder binaryBuilder = new StringBuilder();
 47         for (byte b : bytes) {
 48             binaryBuilder.append(convertByte2BinaryString(b));
 49         }
 50 
 51         int paddingCount = binaryBuilder.length() % 6;
 52         int totalCount = paddingCount > 0 ? binaryBuilder.length() / 6 + 1
 53                 : binaryBuilder.length() / 6;
 54         int actualLength = 6 * totalCount;
 55 
 56         //百分号后面的-号表示长度不够规定长度时,右填充。否则左填充。
 57         return String.format("%-" + actualLength + "s",
 58                 binaryBuilder.toString()).replace(' ', '0');
 59     }
 60 
 61     private static String escapeBinaryString(String binaryString)
 62             throws Exception {
 63         if (null == binaryString || binaryString.isEmpty()
 64                 || binaryString.length() % 6 != 0) {
 65             System.out.println("error");
 66             throw new Exception("escape binary string error.");
 67         }
 68 
 69         StringBuilder escapeBuilder = new StringBuilder();
 70         for (int i = 0; i <= binaryString.length() - 1; i += 6) {
 71             String escapeString = binaryString.substring(i, i + 6);
 72             int index = Integer.parseInt(escapeString, 2);
 73             escapeBuilder.append(INDEX_MAP.get(index));
 74         }
 75 
 76         return escapeBuilder.toString();
 77     }
 78 
 79     private static String paddingEscapeString(String escapeString) {
 80         int paddingCount = escapeString.length() % 4;
 81         int totalCount = paddingCount > 0 ? escapeString.length() / 4 + 1
 82                 : escapeString.length() / 4;
 83         int actualCount = 4 * totalCount;
 84         return String.format("%-" + actualCount + "s", escapeString).replace(
 85                 ' ', PADDING_CHAR);
 86     }
 87 
 88     private static String convertByte2BinaryString(byte b) {
 89         
 90         /**
 91          * 对于非负数,直接使用Integer.toBinaryString方法把它打印出来
 92          */
 93         if (b >= 0) {
 94             StringBuilder builder = new StringBuilder();
 95             builder.append(Integer.toBinaryString(b));
 96             return String.format("%08d", Integer.parseInt(builder.toString()));
 97         } else {
 98             /**
 99              * 对于负数,要记住内存保存的是补码。
100              * 不能直接使用Byte.parseByte()方法。
101              * 因为这个方法最终调的是Integer.parseInt()方法,也就是说,负数如:10000001
102              * 对Integer.parseInt()来说并不会认为是负数,符号位1被当作数值位,是129
103              * 同时Byte.parseByte()方法里还对数值范围做了校验,符号位1,已超出范围,这样
104              * 会抛出异常。而Byte又没有提供toBinaryString的方法
105              * 为了保存byte的二进制值,可利用按位与的方法
106              * 例如有一个负数1000 1111,要把它以字符串保留出来,利用它与1111 1111的与操作,
107              * 再转成int类型。1000 1111 & 1111 1111
108              * 在内存中保存的就是 00000000 10001111,这时保存的是一个正整数。但我们不关心整数的正负,
109              * 因为我们的目的是要把这串字符串截取出来
110              * 再利用Integer.toBinaryString()打印出来。
111              * Integer.toBinaryString()对于正数,会将前面的零去掉,如上将打印出1000 1111,这就是我们要的结果。
112              */
113             int value = b & 0xFF;
114             return Integer.toBinaryString(value);
115         }
116     }
117 
118 }
View Code

相关文章:

  • 2021-07-28
  • 2021-12-11
  • 2022-12-23
  • 2022-12-23
  • 2022-01-27
  • 2022-12-23
  • 2021-11-08
猜你喜欢
  • 2021-07-23
  • 2021-08-27
  • 2021-10-17
  • 2022-12-23
相关资源
相似解决方案