今天用java写md5加密,发现涉及到一些底层的知识,百度一番后做个记录。
我们知道,计算机在保存整数时,会先将其转换为一个二进制数,而后存储。那么,怎样根据计算机保存的二进制数(保存在m个字节上,共有8m位)反推出其代表的整数?
如果保存的是无符号数,那么二进制数代表的整数等于它本身。
如果保存的是有符号数,则首先要看二进制数的最高位,如果是0,那么它代表的整数等于它本身;如果是1,那么它代表一个负整数,这个负整数的绝对值化为二进制后按位取反再加一等于这个二进制数本身。
由此可得,计算机中n位存储空间(n>1)表示有符号数时,能表示的整数的范围是:[-2^(n-1), 2^(n-1)-1]
对计算机保存的有符号数而言,如果需要将其转储到更大的存储空间当中(譬如byte型数据转int型,从8位空间转储到32位空间),那么在新空间中存储的二进制数由旧空间中存储的二进制数高位补0或补1得到。若旧空间中的二进制数最高位是0,则补0;若最高位是1,则补1。
完整代码如下,其余解释见注释:
public static String md5(String text) { try { MessageDigest md = MessageDigest.getInstance("md5"); byte[] result = md.digest(text.getBytes());//result长度固定为16 StringBuffer sb = new StringBuffer(); // Byte型数据可以表示2^8=256种数值,无符号二位十六进制数也恰好可以表示16^2=256种数值 // 这里将每个byte型数据变换成一个长度固定为2的字符串,字符串内容为一个无符号二位十六进制数 for (byte b : result){ int number = b & 0xff; //java中整数默认的数据类型是int,计算 b&0xff 时,0xff默认为int型,故先将b转型为int,再做4个字节上的位与运算 //上一行代码的作用在于,将[-128,127]上的byte型数据一对一映射为[0,255]上的int型数据,以便导入下面的函数 String hex = Integer.toHexString(number); if (hex.length() == 1){ hex = "0"+hex; } sb.append(hex); } return sb.toString(); } catch (NoSuchAlgorithmException e) { e.printStackTrace(); return ""; } }
[链接]详细解释可以参考这篇文章
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)