代码模块:
private static final String[] hexStrings = new String[256];
static{
//将0-255全部分别表示成16进制的字符
for(int i=0;i<256;i++){
StringBuilder sb = new StringBuilder(2);
char ch = Character.forDigit(((byte)i>>4)&0x0F, 16);//取到byte左4位用16进制表示的字符
sb.append(Character.toUpperCase(ch));
ch = Character.forDigit(((byte)i>>4)&0x0F, 16);//取到byte右4位用16进制表示的字符
sb.append(Character.toUpperCase(ch));
hexStrings[i] = sb.toString();
}
}
/**
* 数据签名
* @param signData 要签名的数据
* @param charset 字符编码
* @param signType 签名类型
* @return
* @throws UnsupportedEncodingException
*/
public static String sign(String signData,String charset,String signType) throws UnsupportedEncodingException{
//数据第一步按签名方式加密成字节数组
byte[] digest = DigestUtils.getDigest(signType).digest(signData.getBytes(charset));
StringBuilder sb = new StringBuilder(digest.length*2);
for(byte b:digest){
sb.append(hexStrings[(int)b & 0xFF]);
}
return sb.toString();
}
解析如下:
因为byte是一个字节表示8位,第一步
char ch = Character.forDigit(((byte) i >> 4) & 0x0F, 16);
ch = Character.forDigit((byte) i & 0x0F, 16);
将0-255全部用16进制表示, 0-255如果先向右位移4位,那么接下来表示的
将是前面的4位转换成16进制,再不位移的情况下与0X0F与运算,那么就是
表示的后面4位用16进制表示.
如: 255 : 1111 1111
右移4位 ---> 0000 1111这时候表示16进制就是F
不位移但是与0x0F与运算 ---> 0000 1111 这时候表示的也是F
所以最后255实现SHA256加密之后就是FF
在方法初始话的时候,先讲0-255全部转化成以16进制表示.注意,不管结果是什么都会占用两个字节 0 ---> 00
思想解析:
1.将0-255全部转化成16进制的形式的字符串数组(两个为一组)
2.将要签名的数据转化成byte数组(byte数组为整形范围是(-128~127))但是将数据与0XFF与运算之后范围变成0~255 ((int) b & 0xFF) 注意,byte转int时需要跟0xFF进行与运算,是防止int(32bit)前 24位补1 ,造成错误运算.
3.d.append(hexStrings[(int) b & 0xFF]);转换成byte之后的数据都对应0-255转化成字符串数组的一个数.
4.将所有的结果结合在一起就是签名数据.
---------------------
作者:不起眼的魂
来源:优快云
原文:https://blog.youkuaiyun.com/qq844579582/article/details/54312647
版权声明:本文为博主原创文章,转载请附上博文链接!