as3corelib 的 MD5.digest.endian 应该是 LITTLE_ENDIAN
- 非狐外传 - 赖勇浩的编程私伙局赖勇浩(http://laiyonghao.com). MD5 算法(http://en.wikipedia.org/wiki/MD5)已经是使用最为广泛的信息摘要算法之一,常用以错误检查,比如命令 md5sum. 当我们通过网络传输 protobuf-2.4.1.tar.gz 后,可以在另一端通过比对它的 md5sum 结果是否相同来进行校验.
$ md5sum protobuf-2.4.1.tar.gz dc84e9912ea768baa1976cb7bbcea7b5 protobuf-2.4.1.tar.gz当我们通过网络传输 protobuf-2.4.1.tar.gz 后,可以在另一端通过比对它的 md5sum 结果是否相同来进行校验。
/* Encodes input (UINT4) into output (unsigned char). Assumes len is
a multiple of 4.
*/
static void Encode (output, input, len)
unsigned char *output;
UINT4 *input;
unsigned int len;
{
unsigned int i, j;
for (i = 0, j = 0; j < len; i++, j += 4) {
output[j] = (unsigned char)(input[i] & 0xff);
output[j+1] = (unsigned char)((input[i] >> 8) & 0xff);
output[j+2] = (unsigned char)((input[i] >> 16) & 0xff);
output[j+3] = (unsigned char)((input[i] >> 24) & 0xff);
}
}
/* Decodes input (unsigned char) into output (UINT4). Assumes len is
a multiple of 4.
*/
static void Decode (output, input, len)
UINT4 *output;
unsigned char *input;
unsigned int len;
{
unsigned int i, j;
for (i = 0, j = 0; j < len; i++, j += 4)
output[i] = ((UINT4)input[j]) | (((UINT4)input[j+1]) << 8) |
(((UINT4)input[j+2]) << 16) | (((UINT4)input[j+3]) << 24);
}而上文提到的 md5 wikipedia 页面也有一行代码注释提到应为小端序:var char digest[16] := h0 append h1 append h2 append h3 //(expressed as little-endian)
digest = new ByteArray() digest.writeInt(a); digest.writeInt(b); digest.writeInt(c); digest.writeInt(d); digest.position = 0;当传输 digest 到另一个进程进行比对时,就会发现 md5 检验和不匹配的情况了。
---
src/com/adobe/crypto/MD5.as | 4 +++-
1 files changed, 3 insertions(+), 1 deletions(-)
diff --git a/src/com/adobe/crypto/MD5.as b/src/com/adobe/crypto/MD5.as
index da533cc..db5406a 100644
--- a/src/com/adobe/crypto/MD5.as
+++ b/src/com/adobe/crypto/MD5.as
@@ -34,6 +34,7 @@ package com.adobe.crypto {
import com.adobe.utils.IntUtil;
import flash.utils.ByteArray;
+ import flash.utils.Endian;
/**
* The MD5 Message-Digest Algorithm
*
@@ -178,7 +179,8 @@ package com.adobe.crypto {
c += cc;
d += dd;
}
- digest = new ByteArray()
+ digest = new ByteArray();
+ digest.endian = Endian.LITTLE_ENDIAN;
digest.writeInt(a);
digest.writeInt(b);
digest.writeInt(c);
--
1.7.0.4我已经向 as3corelib 的维护者反映这个问题,估计不日就可以由官方修复。但在官方发布新版本之前,我们也可以选择两个变通方案,一是使用 hexdigest,二是编写一个自己的转换函数 toLittleEndianMd5Digest,把 MD5.digest 转为 LITTLE_ENDIAN,实现如下: function toLittleEndianMd5Digest(ba:ByteArray):ByteArray
{
if(ba.endian == Endian.LITTLE_ENDIAN)
{
return ba;
}
var new_ba:ByteArray = new ByteArray();
new_ba.endian = Endian.LITTLE_ENDIAN;
new_ba.writeInt(ba.readInt());
new_ba.writeInt(ba.readInt());
new_ba.writeInt(ba.readInt());
new_ba.writeInt(ba.readInt());
new_ba.position = 0;
return new_ba;
}
... // 省略业务代码
// 在用到 MD5.digest 的地方
var md5:ByteArray = toLittleEndianMd5Digest(MD5.digest);这个 toLittleEndianMd5Digest 函数能够在 as3corelib 修正这个 bug 以后保持兼容,所以不用担心后遗症,可以放心大胆地使用。