Character encoding 带有ASCII字符的MD5

Character encoding 带有ASCII字符的MD5,character-encoding,md5,Character Encoding,Md5,我有一根绳子 wDevCopyright = [NSString stringWithFormat:@"Copyright: %c 1995 by WIRELESS.dev, Corp Communications Inc., All rights reserved.",0xa9]; 为了咀嚼它,我打电话给你 -(NSString *)getMD5:(NSString *)source { const char *src = [source UTF8String]; unsign

我有一根绳子

    wDevCopyright = [NSString stringWithFormat:@"Copyright: %c 1995 by WIRELESS.dev, Corp Communications Inc., All rights reserved.",0xa9];
为了咀嚼它,我打电话给你

-(NSString *)getMD5:(NSString *)source
{

 const char *src = [source UTF8String];
 unsigned char result[CC_MD5_DIGEST_LENGTH];
 CC_MD5(src, strlen(src), result);

     return [NSString stringWithFormat:
   @"%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x",
   result[0], result[1], result[2], result[3], 
   result[4], result[5], result[6], result[7],
   result[8], result[9], result[10], result[11],
   result[12], result[13], result[14], result[15]
   ]; //ret;
}
因为0xa9*src=[source UTF8String]没有创建表示字符串的字符,因此返回的munge与其他平台不可比较

我试图用NSASCIIStringEncoding对字符进行编码,但它破坏了代码

如何使用包含ASCII字符的字符串调用CC_MD5,并获得与Java中相同的哈希值


更新代码请求:

爪哇

结果>>>>>消息##\251\251 md5 a252c2c85a9e7756d5ba5da9949d57ed

ObjC

结果>>>objC msg##int 169 char©md5:9b759040321a408a5c7768b4511287a6

**如前所述,没有0xa9,Java和ObjC中的哈希是相同的。我试图在Java和ObjC中获得相同的0xa9哈希值


JavaMD5代码

private static char[] kTestASCII = {
    169
    };

md5(new String(kTestASCII), false);

    /**
     * Compute the MD5 hash for the given String.
     * @param s the string to add to the digest
     * @param unicode true if the string is unciode, false for ascii strings
     */
    public synchronized final String md5(String value, boolean unicode)
    {
        MD5();
        MD5.update(value, unicode);
        return WUtilities.toHex(MD5.finish());

    }
    public synchronized void update(String s, boolean unicode)
{


    if (unicode)
    {
        char[] c = new char[s.length()];
        s.getChars(0, c.length, c, 0);
        update(c);
    }
    else
    {
        byte[] b = new byte[s.length()];
        s.getBytes(0, b.length, b, 0);
        update(b);
    }
}

public synchronized void update(byte[] b)
{
    update(b, 0, b.length);
}

//--------------------------------------------------------------------------------

/**
 * Add a byte sub-array to the digest.
 */
public synchronized void update(byte[] b, int offset, int length)
{
    for (int n = offset; n < offset + length; n++)
        update(b[n]);
}

/**
 * Add a byte to the digest.
 */
public synchronized void update(byte b)
{
    int index = (int)((count >>> 3) & 0x03f);
    count += 8;
    buffer[index] = b;
    if (index >= 63)
        transform();
}
private static char[]kTestASCII={
169
};
md5(新字符串(kTestASCII),false);
/**
*计算给定字符串的MD5哈希。
*@param s要添加到摘要中的字符串
*@param unicode如果字符串为uncode,则为true;如果字符串为ascii,则为false
*/
公共同步最终字符串md5(字符串值,布尔unicode)
{
MD5();
MD5.更新(值,unicode);
返回WUtilities.toHex(MD5.finish());
}
公共同步的无效更新(字符串s,布尔unicode)
{
if(unicode)
{
char[]c=新字符[s.length()];
s、 getChars(0,c.length,c,0);
更新(c);
}
其他的
{
字节[]b=新字节[s.length()];
s、 getBytes(0,b.length,b,0);
更新(b);
}
}
公共同步的无效更新(字节[]b)
{
更新(b,0,b.长度);
}
//--------------------------------------------------------------------------------
/**
*将字节子数组添加到摘要中。
*/
公共同步无效更新(字节[]b,整数偏移量,整数长度)
{
对于(int n=偏移;n<偏移+长度;n++)
更新(b[n]);
}
/**
*在摘要中添加一个字节。
*/
公共同步无效更新(字节b)
{
int索引=(int)((计数>>>3)和0x03f);
计数+=8;
缓冲区[索引]=b;
如果(索引>=63)
transform();
}

我认为我的问题在于使用NSData进行编码,而不是使用C字符[]或Java字节[]。那么,在objC中将我自己的字节滚动成字节[]的最佳方式是什么呢?

stringWithCString
需要一个以null结尾的C字符串。我认为在Objective-C代码中,
kTestASCII[]
不一定以null结尾。也许这就是造成差异的原因

尝试:


您遇到问题的字符是Unicode。此字符的正确UTF-8编码是字节序列
0xc9 0xa9

但是,您正在尝试从不是任何字符的有效UTF-8编码的单字节序列
0xa9
进行转换。见表3-7。由于这不是有效的UTF-8字节序列,
stringWithCString
正在将输入转换为Unicode。当这个字符被编码回UTF-8时,它产生字节序列
0xef 0xbf 0xbd
。正如您的Objective-C示例所报告的,此序列的MD5是9b759040321a408a5c7768b4511287a6

您的Java示例生成了a252c2c85a9e7756d5ba5da9949d57ed的MD5,简单的实验表明它是字节序列
0xa9
的MD5,我已经注意到它不是所需字符的有效UTF-8表示

我认为我们需要了解您正在使用的Java md5()方法的实现。我怀疑这只是简单地删除每个Unicode字符的高位字节,以转换为字节序列,以便传递给MessageDigest类。这与使用UTF-8编码的Objective-C实现不匹配

注意:即使您修改了Objective-C实现以匹配Java md5()方法的编码,您的测试也需要进行一些调整,因为您不能将
stringWithCString
NSUTF8StringEncoding
编码一起使用来将字节序列
0xa9
转换为NSString

更新

现在已经看到了使用不推荐的方法的Java实现,我的建议是更改Java实现,如果可能的话,使用适当的UTF-8编码


然而,我怀疑您的需求与当前的Java实现相匹配,即使它是错误的。因此,我建议您使用
NSString getCharacters:range:
来检索
unichar
s数组,然后通过获取每个unichar的低位字节手动创建一个字节数组,从而复制Java不推荐使用的getBytes()方法的不良行为。

多亏了GBegan的解释-这是我的解决方案

for(int c = 0; c < [s length]; c++){
    int number = [s characterAtIndex:c];
    unsigned char c[1];
    c[0] = (unsigned char)number;
    NSMutableData *oneByte = [NSMutableData dataWithBytes:&c length:1];
}
for(int c=0;c<[s长度];c++){
整数=[s characterAtIndex:c];
无符号字符c[1];
c[0]=(无符号字符)编号;
NSMutableData*oneByte=[NSMutableData dataWithBytes:&c长度:1];
}

请说明您的问题好吗?我们喜欢在这里看到明确的问题。感谢您指导我成为一个更好的列表公民。您的Java代码是什么样子的?结果为空终止符>>>>objC msg###int 169 char©md5:9b759040321a408a5c7768b4511287a6与前面的帖子相同。很抱歉,这没有帮助。在Objective-C测试代码中,这只是我突然想到的一个缺陷,尽管这显然是一个良性缺陷。我将把Java代码添加到post中。
private static char[] kTestASCII = {
    169
    };

md5(new String(kTestASCII), false);

    /**
     * Compute the MD5 hash for the given String.
     * @param s the string to add to the digest
     * @param unicode true if the string is unciode, false for ascii strings
     */
    public synchronized final String md5(String value, boolean unicode)
    {
        MD5();
        MD5.update(value, unicode);
        return WUtilities.toHex(MD5.finish());

    }
    public synchronized void update(String s, boolean unicode)
{


    if (unicode)
    {
        char[] c = new char[s.length()];
        s.getChars(0, c.length, c, 0);
        update(c);
    }
    else
    {
        byte[] b = new byte[s.length()];
        s.getBytes(0, b.length, b, 0);
        update(b);
    }
}

public synchronized void update(byte[] b)
{
    update(b, 0, b.length);
}

//--------------------------------------------------------------------------------

/**
 * Add a byte sub-array to the digest.
 */
public synchronized void update(byte[] b, int offset, int length)
{
    for (int n = offset; n < offset + length; n++)
        update(b[n]);
}

/**
 * Add a byte to the digest.
 */
public synchronized void update(byte b)
{
    int index = (int)((count >>> 3) & 0x03f);
    count += 8;
    buffer[index] = b;
    if (index >= 63)
        transform();
}
char kTestASCII [] = {
            169,
            0
        };
for(int c = 0; c < [s length]; c++){
    int number = [s characterAtIndex:c];
    unsigned char c[1];
    c[0] = (unsigned char)number;
    NSMutableData *oneByte = [NSMutableData dataWithBytes:&c length:1];
}