实际项目中,出现在windows下,通过eclipse启动运行正常,然而export发布的jar运行不正常的情况。通过跟踪分析。发现是由
String.getBytes 造成MD5算法结果不一致。
未修改前代码段如下:
private static String c(String requestParams,int len){
String sign = "";
try {
MessageDigest messageDigest = MessageDigest.getInstance("MD5");
messageDigest.update(requestParams.getBytes());
String updateLen = String.format("%d",len + 48);
messageDigest.update(updateLen.getBytes());
byte[] bytesDigest = messageDigest.digest();
char hexDigits[] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' };
int j = bytesDigest.length;
char str[] = new char[j * 2];
int k = 0;
for (int i = 0; i < j; i++) {
byte byte0 = bytesDigest[i];
str[k++] = hexDigits[byte0 >>> 4 & 0xf];
str[k++] = hexDigits[byte0 & 0xf];
}
sign = new String(str);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return sign;
}
修改后的代码:
private static String c(String requestParams,int len){
String sign = "";
try {
MessageDigest messageDigest = MessageDigest.getInstance("MD5");
messageDigest.update(requestParams.getBytes("utf-8"));
String updateLen = String.format("%d",len + 48);
messageDigest.update(updateLen.getBytes("utf-8"));
byte[] bytesDigest = messageDigest.digest();
char hexDigits[] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' };
int j = bytesDigest.length;
char str[] = new char[j * 2];
int k = 0;
for (int i = 0; i < j; i++) {
byte byte0 = bytesDigest[i];
str[k++] = hexDigits[byte0 >>> 4 & 0xf];
str[k++] = hexDigits[byte0 & 0xf];
}
sign = new String(str);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return sign;
}
原因:
/**
* Encodes this {@code String} into a sequence of bytes using the
* platform's default charset, storing the result into a new byte array.
*
* <p> The behavior of this method when this string cannot be encoded in
* the default charset is unspecified. The {@link
* java.nio.charset.CharsetEncoder} class should be used when more control
* over the encoding process is required.
*
* @return The resultant byte array
*
* @since JDK1.1
*/
public byte[] getBytes() {
return StringCoding.encode(value, 0, value.length);
}
未指定的话,将会采用平台默认的字符集,而这是不可控的。