質問
これは私の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]];
結果は####################©len 2 [データ説明] = "<" c2a9>
MD5:A541ECDA3D4C67F1151CAD507563423
Javaで同じ関数を実行すると、
">>>>> msg ## 251 251
MD5 A252C2C85A9E7756D5BA5DA9949D57ED
問題は、私がJavaで得るのと同じバイトをOBJCで取得する最良の方法は何ですか?
解決 2
別の投稿での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];
}
他のヒント
ASCIIはエンコーディングであるため、「ASCIIからNSDATA」は意味がありません。文字をエンコードした場合、データがあります。
エンコーディングとは、理想的なユニコード文字(コードポイント)を、UTF-16のサロゲートペアなどのシーケンスで、1つまたは数のバイト単位(コード単位)に変換することです。
NSStringは、多かれ少なかれ理想的なユニコードオブジェクトです。に含まれています 文字 エンコード*に関係なく、unicodeの文字列の。
ASCIIはエンコーディングです。 UTF-8もエンコーディングです。文字列に尋ねるとき UTF8String
, 、あなたはそのキャラクターをUTF-8としてエンコードするように頼んでいます。
NSData *data = [NSData dataWithBytes:[source UTF8String] length:[source length]];
結果は次のとおりです
######### source © [data description] = "<"c2>
それはあなたが間違った長さを渡したからです。文字列の長さ(文字内)は、いくつかのエンコードのコード単位(この場合はバイト)の数と同じではありません。
正しい長さはです strlen([source UTF8String])
, 、しかし、それはあなたにとってより簡単で、実行時により速く使用する dataUsingEncoding:
文字列にNSDATAオブジェクトを作成するように依頼します。
エンコードを変更するとき
NSData *data = [NSData dataWithBytes:[source UTF8String] length:[source lengthOfBytesUsingEncoding:NSUTF8StringEncoding]];
エンコーディングを変更しませんでした。まだUTF-8としてエンコードしています。
使用する dataUsingEncoding:
.
問題は、私がJavaで得るのと同じバイトをOBJCで取得する最良の方法は何ですか?
同じエンコーディングを使用します。
「拡張ASCII」のようなものはありません。 ISO 8859-1、ISO 8859-9、マクロマン、Windows CodePage 1252、UTF-8など、ASCIIに基づいている(または少なくとも互換性がある)いくつかの異なるエンコードがあります。どちらの意味を決定し、文字列にそのキャラクターをエンコードするように指示する必要があります。
さらに良いことに、UTF-8を使用し続けます。これは、ほとんどの場合、ほとんどがASSIIテキストの正しい選択です。代わりにJavaコードを変更します。
NSData *data = [source dataUsingEncoding:NSASCIIStringEncoding];
結果:
[data description] = (null)
True ASCIIは、128の可能な文字のみをエンコードできます。 UnicodeにはすべてのASCIIが変更されていないため、Unicodeの最初の128コードポイントはASCIIがエンコードできるものです。それ以外の場合、ASCIIはエンコードできません。
私は見た NSASCIIStringEncoding
に相当するように振る舞います NSISOLatin1StringEncoding
前;彼らはそれを純粋なASCIIエンコーディングに変えたかもしれないように聞こえますが、もしそうなら、それは良いことです。 ASCIIには著作権記号はありません。ここで見るものは正しい結果です。
*これはまったく真実ではありません。文字はUTF-16として露出されているため、基本的な多言語平面外の文字は、本当に理想的な文字列オブジェクトにあるため、キャラクター全体ではなく代理ペアとして露出します。これはトレードオフです。 Swiftでは、組み込みの文字列タイプは完璧な理想的なユニコードオブジェクトです。文字は文字であり、エンコードされるまで分割されません。しかし、NSString(SwiftまたはObjective-Cであろうと)で作業する場合、あなたに関する限り、それを理想的な文字列として扱う必要があります。