challenge UTF-16をUTF-8に変換

UTF-16の文字コードを16進(1オクテットごとにスペース区切り)の形で入力します。入力した文字コードを、2進数の形(1オクテットごとにスペース区切り)で出力してください。

入力する文字コードはUCS-2の範囲(サロゲートペアを使わなくてもよい範囲)のみに限定しても構いませんが、可能ならばサロゲートペアにも対応したものに挑戦してください。

  • 例1: abc(U+0041 U+0042 U+0043)
    • 入力 00 41 00 42 00 43
    • 出力 01000001 01000010 01000011
  • 例2: あいう(U+3042 U+3044 U+3046)
    • 入力 30 42 30 44 30 46
    • 出力 11100011 10000001 10000010 11100011 10000001 10000100 11100011 10000001 10000110

正攻法からトリッキーな手段まで、いろいろお待ちしております。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
#include <stdio.h>                  
#include <stdlib.h>                 
#include <string.h>                 

typedef unsigned short utf16char; /* sizeof(short) >= 2 octets */
#define UTF8_MAXOCTETS 3 /* UCS-2ではutf-8にしたとき3 octets以内に収まる */
typedef struct{                                                           
        int len;                                                          
        char data[UTF8_MAXOCTETS];                                        
} Utf8char;                                                               

void encode(Utf8char *utf8, utf16char utf16){
        int i, len;                          

        if(!(utf16 & (~0x7f))) len = 1;
        else if(!(utf16 & (~0x7ff))) len = 2;
        else len = 3;                        

        switch(len){
        case 1:     
                utf8->data[0] = utf16 & 0x7f;
                break;                       
        case 2:                              
                utf8->data[0] = (utf16>>6 & 0x1f) | 0xc0;
                utf8->data[1] = (utf16 & 0x3f) | 0x80;   
                break;                                   
        case 3:                                          
                utf8->data[0] = (utf16>>12 & 0xf) | 0xe0;
                utf8->data[1] = (utf16>>6 & 0x3f) | 0x80;
                utf8->data[2] = (utf16 & 0x3f) | 0x80;   
                break;                                   
        }                                                
        utf8->len = len;                                 
}                                                        

void print_bin(char c){
        printf("%d%d%d%d%d%d%d%d ", c>>7&1, c>>6&1, c>>5&1, c>>4&1, c>>3&1, c>>2&1, c>>1&1, c&1);
}                                                                                                

int main(int argc, char **argv){
        int bytes = argc-1, len = bytes / 2;
        int i, j;
        utf16char *utf16;
        char *utf8;
        int u8len = 0;
        Utf8char u8char;

        if(!bytes) return 0;
        if(bytes % 2){
                printf("Invalid input.\n");
                return 1;
        }
        utf16 = malloc(sizeof(utf16char)*len);
        utf8 = malloc(len*UTF8_MAXOCTETS);

        for(i=0,j=1;i<len;i++,j+=2) utf16[i] = strtol(argv[j], NULL, 16)<<8 | strtol(argv[j+1], NULL, 16);

        for(i=0;i<len;i++){
                encode(&u8char, utf16[i]);
                memcpy(utf8 + u8len, u8char.data, u8char.len);
                u8len += u8char.len;
        }
        for(i=0;i<u8len;i++) print_bin(utf8[i]);
        putchar('\n');

        free(utf16);
        free(utf8);
}

Posted feedbacks

Number of comments:9 Nested Flatten
  1. 2 Scheme Python
  2. 1 Groovy C SQL Smalltalk Perl

Index

Feed

Other

Link

Pathtraq

loading...