《Md5加密中为什么要 & 0xff》
这里首先要搞明白一个代理(自己设想的):
* byte有8位,假如全部都是 11111111 那么对应的int(10进制)类型就是 255
* 虽然255(十进制)和11111111(二进制)都表示同一个数,但作为String类型存储255作为String类型存储长度为3,而11111111作为string类型存储长度为8
* 【关键点一:】MessageDigest.getInstance("MD5").digest("需要加密的字符".getBytes()) 计算出来的结果返回的byte[]长度始终为16位。
* 所以说,真正的密文 是由java别人大神写的算法计算出来的。已经保证16位的固定长度的byte
* 【关键点二:】要记住我们计算出来的md5(32位)最后都都是固定长度32的字符串
* 那么问题出现了:byte[16]这个数组要是直接转化为int类型在存储为字符。而byte的取值范围为-128~127.那么作为0-99转化为总长度为16的字符串没有问题,
* 但,100~128和-10~-128这些数字转换为总长度为16的字符串就不一定了。
* 因为一个byte数可以是-10(转换为String长度为3)那么这样的16个byte总长度就变成了3*16=48
* 注意:-128~127一共有256个数字。
* 即:{1~127}有127个
* {-1~-128}有128个
* 0 有 1个
* 得:127+128+1=256
* 那么就需要单独用一个字符位表示256个数字就需要用到256进制。
* 【常规一:】十进制 一个字符位可以表示10个字符{0,1,2,3,4,5,6,7,8,9}
* 如果不想将md5生成的密文(byte & 0xff)二直接保存为16个定长度的字符。那么就需要256进制的数字来形容
* 【注意:】应为负数转为字符串会占用2个长度,应为符号占用一个长度。所以最精简的方法就是用256进制表示,刚好可以满足byte的取值范围将其一一对应。
* 【总结一:】直接将byte[16]转换为一个长度为16的字符需要【256】进制的数来做直接替换。
* 那么现在问题来了,字符串中单个字符就能代表到255的符号需要怎么来表示?
* 当然这是数学家的问题,我们只是苦逼的程序员。即使你想出来了,也没有权威,别人也不会用。
* 【常规二:】java虚拟机有16精制的数。并且能用1个字符表示{0~15}即{0,1,2,3,4,5,6,7,8,9,a,b,c,d,e,f}。
* 对应的JAVA方法为Integer.toHexString(k),k为int类型的数。
* 那么一个16精制的正数最大为 f---->(十进制)15
* 两个16进制的正数最大为 ff---->(十进制)15*16+15=255
* 那么对于从0 到ff一个有多少个数为:
* 0---》1个
* 1~ff--》256个
* 刚好和byte的取值范围{-128~127}共256个数字可以一一对应。
* 对应的JAVA方法为Integer.toHexString(k),k为int类型的数。
* 那么一个16精制的正数最大为 f---->(十进制)15
* 两个16进制的正数最大为 ff---->(十进制)15*16+15=255
* 那么对于从0 到ff一个有多少个数为:
* 0---》1个
* 1~ff--》256个
* 刚好和byte的取值范围{-128~127}共256个数字可以一一对应。
* 【总结二:】如果用16进制的2位数来表示一个byte字节的值,在保证不出现负数的情况下刚好可以完全替换。
* 只不过对于0-f(15)这样的一个长度的字符串转换为字符串时。为了保证和两位数的16进制保持一致都占用两个长度的字符串,
* 需要将不足长度的在前面用0补齐。
* 【总结三:】将byte[16]全部转换为正数的16进制字符串刚好是32位。
* 即Md5生成的byte[16]固定长度的规律可以得到固定转换为16精制的数表示为固定长度为32的字符串。
* 当然,你如果觉得用负数替换,保证固定长度。不足的位数用你自己定义的符号去替换当然可以使用.
* (解密也需要用你自己定义的符号去计算解密,挨个找出原来的byte[16]个字节)
* 只不过,在md5算出来的密文中,大家都约定束城了用什么样的字符去替换。
* 【总结四:】那么在byte[16]转换为16进制的固定长度32的字符串。并不是为了什么,就是为了保证我们可以直观看到的密文都是固定长度的。
* 延续了在byte[16]这个固定长度的特点。提高了md5的加密的高大上。那么对于每一个byte[16]中的单个byte转换到对应16进制的的二位数
* 只需要保证都是唯一,一一对应的就行了(保证可逆)(md5算出来的密文byte[16]是不可逆的)。
* 那么 对于需要加密的密文 "xxxx"-----(不可逆)-->Md5(byte[16])<-----可逆---->16进制的32个长度的字符串。
* 就可以简化为 "xxxx"------(不可逆)---->16进制的32个长度的字符串。
* 想想上面这段推理大家都看得懂。
* 那么对于通用Md5加密后生产32个长度固定的字符串java逻辑为:
*
/**
* 获取md5密文
* @param pwd 未加密的密码
* @return
*/
private static String getmd5(String pwd) {
StringBuffer str=new StringBuffer();
try {
MessageDigest md = MessageDigest.getInstance("MD5");
byte[] digest = md.digest(pwd.getBytes());
for(int i=0;i