読者です 読者をやめる 読者になる 読者になる

NSStringから各エンコーディングの文字コードを取り出す

エンジニアブログで絵文字の事など書いたけれども、実際あまり深く理解していないのでメモ。

NSStringはUnicodeのUTF16実装のラッパークラスだという事はわかった(※1)

だけど、NSStringのリファレンスを読んでも、いろいろなエンコーディングに変換した際の文字コードを取り出す方法がハッキリしない。とりあえず実態はUTF-16なので、UTF-16での文字コードを取り出すのは以下の方法で出来る。

- (NSString *)getCharCodeUTF16:(NSString *)input
{
    int stringLength = [input length];
    NSString *utf16 = @"";
    for (int i = 0; i < stringLength; i++) {
        unichar c = [input characterAtIndex:i];
        utf16 = [utf16 stringByAppendingFormat:@" 0x%02X",c];
    }
    return utf16;
} 

unicharはそもそもUTF-16文字なので、当たり前。では、UTF-8での文字コードを取り出したい場合はどうか、というと、

- (const char *)UTF8String

までは辿りついたのだけれど、const charから文字コードを取り出す方法がわからなかった。

- (NSData *)dataUsingEncoding:(NSStringEncoding)encoding

を使うとなんとかなりそうだったけど、結局NSDataから文字コードを取り出す方法がわからんくて断念。。。。

結局、間に合わせのやり方として、以下の方法であれば、何とかUTF-8文字コードが取り出せる。

- (NSString *)getCharCodeUTF8:(NSString *)input
{
    NSString *escapedUrlString = [input stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
    NSString *utf8 = [escapedUrlString stringByReplacingOccurrencesOfString:@"%" withString:@" 0x"];
    return utf8;
}

エンコーディングを指定して、URLエスケープする方法は用意されているのだ。なんでそこだけ手厚く対応されているのだ。。。どうにかして素直に文字コードを取り出す方法は無いものか。。。

(追記)

「わからんなぁ」とかつぶやいたらstackoverflowのページを教えて貰えました。UTF-8文字コードなら以下の方法で取り出せました

- (NSString *)stringToHex:(NSString *)string
{
    const char *utf8 = [string UTF8String];
    NSMutableString *hex = [NSMutableString string];
    while ( *utf8 ) [hex appendFormat:@"%02X" , *utf8++ & 0x00FF];
    return [NSString stringWithFormat:@"%@", hex];
}

ありがたやー

(追記2)

何か勘違いしていて、dataWithEncodingの存在を放置していたんですが、dataWithEncodingでNSDataを取って、1バイトずつ読めばちゃんと文字コードが取れますね失礼しました。

そんなわけで以下のようなやり方が最適だと思います。

- (NSString *)getCharCode:(NSString *)string encoding:(NSStringEncoding)encoding
{
    NSData *data = [string dataUsingEncoding:encoding];
    NSUInteger length = data.length;
    NSString *code = @"";
    for (NSUInteger i=0;i<length;++i) {
        unsigned char aBuffer[1];
        [data getBytes:aBuffer range:NSMakeRange(i,1)];
        code = [code stringByAppendingFormat:@"0x%02X", aBuffer[0]];
    }
    return code;
}

※1...参考ページ Objective-C: NSString