0

これは、私の MD5 問題の別の亀裂です。問題が ASCII 文字 © (0xa9, 169) にあることはわかっています。文字を文字列に挿入する方法か、上位バイトと下位バイトの問題のどちらかです。

もし私が

 NSString *source = [NSString stringWithFormat:@"%c", 0xa9];

    NSData *data = [source dataUsingEncoding:NSASCIIStringEncoding];

    NSLog(@"\n\n ############### source %@ \ndata desc %@", source, [data description]);

CC_MD5([data bytes], [data length], 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]
   ];

結果:

######### ソース ©

[データの説明] = (null)
md5: d41d8cd98f00b204e9800998ecf8427e

値: int 169 char ©

エンコーディングを変更すると

NSData *data = [NSData dataWithBytes:[source UTF8String] length:[source length]];

結果は

######### ソース ©

[データ記述] = "<"c2>
md5: 6465dad1d31752be3f3283e8f70feef7

エンコーディングを変更すると

NSData *data = [NSData dataWithBytes:[source UTF8String] length:[source lengthOfBytesUsingEncoding:NSUTF8StringEncoding]];

結果は ################ source © len 2 [data description] = "<"c2a9>
md5: a541ecda3d4c67f1151cad5075633423

Javaで同じ関数を実行すると、

">>>>> msg## \251 \251
md5 a252c2c85a9e7756d5ba5da9949d57ed

問題は、Java で取得したのと同じバイトを objC で取得する最良の方法は何ですか?

4

2 に答える 2

6

ASCII はエンコーディングであるため、「ASCII から NSData」は意味がありません。エンコードされた文字がある場合は、データがあります。

エンコーディングとは、理想的な Unicode 文字 (コード ポイント) を 1 バイト以上の単位 (コード単位) に変換することであり、UTF-16 のサロゲート ペアなどのシーケンスである可能性があります。

NSString は多かれ少なかれ理想的な Unicode オブジェクトです。エンコーディングに関係なく、文字列の文字が Unicode で含まれます*。

ASCII はエンコーディングです。UTF-8 もエンコーディングです。文字列に をUTF8String要求すると、その文字を UTF-8 としてエンコードするように要求されます。

NSData *data = [NSData dataWithBytes:[source UTF8String] length:[source length]];

結果は

 ######### source ©
 [data description] = "<"c2>

それは、間違った長さを渡したからです。一部のエンコーディングでは、文字列の長さ (文字単位) がコード単位 (この場合はバイト) の数と同じではありません。

正しい長さは ですが、文字列に NSData オブジェクトを作成するように要求するためstrlen([source UTF8String])に使用する方が簡単で、実行時に高速です。dataUsingEncoding:

エンコーディングを変更すると

NSData *data = [NSData dataWithBytes:[source UTF8String] length:[source lengthOfBytesUsingEncoding:NSUTF8StringEncoding]];

エンコーディングを変更していません。あなたはまだUTF-8としてエンコードしています。

を使用しdataUsingEncoding:ます。

問題は、Java で取得したのと同じバイトを objC で取得する最良の方法は何ですか?

同じエンコーディングを使用します。

「拡張 ASCII」などというものはありません。ISO 8859-1、ISO 8859-9、MacRoman、Windows コードページ 1252、および UTF-8 を含む、ASCII に基づく (または少なくとも互換性のある) いくつかの異なるエンコーディングがあります。どちらを意味するかを決定し、その文字をそれでエンコードするように文字列に指示する必要があります。

さらに良いのは、UTF-8 を引き続き使用することです (大部分が ASCII のテキストには、ほとんど常に UTF-8 が正しい選択です)。代わりに Java コードを変更してください。

NSData *data = [source dataUsingEncoding:NSASCIIStringEncoding];

結果:

[data description] = (null)

真の ASCII は 128 文字しかエンコードできません。Unicode には変更されていない ASCII がすべて含まれているため、Unicode の最初の 128 コード ポイントが ASCII でエンコードできるものです。それ以外の場合、ASCII はエンコードできません。

以前NSASCIIStringEncodingと同等の動作を見てきました。NSISOLatin1StringEncoding純粋な ASCII エンコーディングに変更された可能性があるようです。その場合、それは良いことです。ASCII には著作権記号はありません。ここに表示されているのは正しい結果です。


*これは正確ではありません。文字は UTF-16 として公開されるため、基本多言語面の外部にある文字はすべて、真に理想的な文字列オブジェクトのように文字全体ではなく、サロゲート ペアとして公開されます。これはトレードオフです。Swift では、組み込みの String 型は完全に理想的な Unicode オブジェクトです。文字は文字であり、エンコードされるまで決して分割されません。しかし、(Swift であれ Objective-C であれ) NSString を使用する場合は、それを理想的な文字列として扱う必要があります。

于 2010-11-24T20:36:18.147 に答える
1

別の投稿での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];

}

于 2010-11-27T20:45:12.873 に答える