Obj-C的MD5哈希值与Java/SQL不匹配

8

我想把一个Unicode字符串通过MD5哈希函数处理,并将结果编码为Base64。我需要MSSQL、Java和Obj-C都返回相同的结果。我已经让MSSQL和Java达成了一致,但是我无法使用Obj-C得到相同的结果。

Java代码(返回“SC0RfYWqWLK/YNpIDdGi8w==”)

String input = "chinese lorem ipsum 槏殟殠巘斖蘱飣偓啅撱簻臗";
MessageDigest md = MessageDigest.getInstance("MD5");
byte[] inputBytes = input.getBytes("UTF-16LE");
md.update(input.getBytes("UTF-16LE"));
byte[] enc = md.digest();
String md5Sum = new sun.misc.BASE64Encoder().encode(enc);
System.out.println(md5Sum);

MSSQL代码(返回“SC0RfYWqWLK/YNpIDdGi8w==”)

DECLARE @Str nvarchar(200)
SET @Str = N'chinese lorem ipsum 槏殟殠巘斖蘱飣偓啅撱簻臗'
DECLARE @Bin varbinary(max)
SET @Bin = HashBytes('MD5', @Str);
DECLARE @Hash char(24)
SET @Hash = CAST(N'' AS XML).value('xs:base64Binary(sql:variable("@Bin"))', 'NVARCHAR(MAX)')
PRINT @Hash

Obj-C 代码(返回“vZRPxuE84whftlx697i/Ig==”)

NSString *input = @"chinese lorem ipsum 槏殟殠巘斖蘱飣偓啅撱簻臗";
NSData *data = [input dataUsingEncoding:NSUnicodeStringEncoding allowLossyConversion:NO];
unsigned char digest[CC_MD5_DIGEST_LENGTH];
CC_MD5(data.bytes, data.length, digest);
NSData *hashData = [[NSData alloc] initWithBytes:digest length: sizeof digest];
NSString *base64 = [hashData base64EncodedString];
NSLog(@"%@", base64);

请你帮我让Obj-C返回与其他语言相同的值。它将在iOS应用程序中运行。谢谢。


2
我不是专家,只是猜测 - 你尝试过使用NSUTF16LittleEndianStringEncoding编码从字符串初始化数据吗? - Eimantas
NSUTF16LittleEndianStringEncoding可以正常工作!谢谢。我该如何接受您的答案? - UserNYC
你不需要这样做。那只是一条评论。我现在会将它发布为答案。 - Eimantas
2个回答

6

不是专家,但猜测一下——您尝试使用NSUTF16LittleEndianStringEncoding编码来从字符串初始化数据了吗?


1

我怀疑问题可能是Java和MSSQL在字符串开头没有添加字节顺序标记,而使用NSUnicodeStringEncoding的dataUsingEncoding:allowLossyConversion:则会添加。

您可以通过检查Java和Objective-C中实际UTF-16数据的大小(如果这不是问题,则甚至可以检查实际内容)来验证此假设。


据我所知,NSUnicodeStringEncoding使用UTF-16 LE编码。但很可能情况是NSUnicodeStringEncoding会在前面添加标记,而NSUTF16LittleEndianStringEncoding则不会添加。验证字节顺序标记是否是问题并且如果是问题,使用NSUTF16LittleEndianStringEncoding是否可以解决或者仍需手动删除,这应该不难确定。 - Analog File

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接