プログラマメモ2

2010-11-13

[java]JIS X 0213(JIS2000/2004)のサロゲートペアです。


Javaです。文字です。ユニコードです。サロゲートペアです。
JIS X 0213(JIS2000/2004)のサロゲートペアです。
文字むずかしいですね。コンピュータ上の文字の歴史を知るとおもしろいです。漢字が使えること、日本語のおもしろさってあるなーと思います。



前回作成したメソッドが正しいかテストを兼ねて、ここにある表をベースに出力してみます。
JIS X 0213:2000/2004 surrogate pairs

とりあえず一覧

U+2000B
U+2123D
U+2131B
U+2146E
U+218BD
U+20B9F
U+216B4
U+21E34
U+231C4
U+235C4
U+2373F
U+23763
U+23CFE
U+247F1
U+2548E
U+2550E
U+25771
U+259C4
U+25DA1
U+26AFF
U+26E40
U+270F4
U+27684
U+28277
U+283CD
U+2A190
U+20089
U+200A2
U+200A4
U+201A2
U+20213
U+2032B
U+20381
U+20371
U+203F9
U+2044A
U+20509
U+205D6
U+20628
U+2074F
U+20807
U+2083A
U+208B9
U+2097C
U+2099D
U+20AD3
U+20B1D
U+20D45
U+20DE1
U+20E95
U+20E6D
U+20E64
U+20F5F
U+21201
U+21255
U+2127B
U+21274
U+212E4
U+212D7
U+212FD
U+21336
U+21344
U+213C4
U+2146D
U+215D7
U+26C29
U+21647
U+21706
U+21742
U+219C3
U+21C56
U+21D2D
U+21D45
U+21D78
U+21D62
U+21DA1
U+21D9C
U+21D92
U+21DB7
U+21DE0
U+21E33
U+21F1E
U+21F76
U+21FFA
U+2217B
U+2231E
U+223AD
U+226F3
U+2285B
U+228AB
U+2298F
U+22AB8
U+22B4F
U+22B50
U+22B46
U+22C1D
U+22BA6
U+22C24
U+22DE1
U+231C3
U+231F5
U+231B6
U+23372
U+233D3
U+233D2
U+233D0
U+233E4
U+233D5
U+233DA
U+233DF
U+2344A
U+23451
U+2344B
U+23465
U+234E4
U+2355A
U+23594
U+23639
U+23647
U+23638
U+2363A
U+2371C
U+2370C
U+23764
U+237FF
U+237E7
U+23824
U+2383D
U+23A98
U+23C7F
U+23D00
U+23D40
U+23DFA
U+23DF9
U+23DD3
U+23F7E
U+24096
U+24103
U+241C6
U+241FE
U+243BC
U+24629
U+246A5
U+24896
U+24A4D
U+24B56
U+24B6F
U+24C16
U+24D14
U+24E0E
U+24E37
U+24E6A
U+24E8B
U+2504A
U+25055
U+25122
U+251A9
U+251E5
U+251CD
U+2521E
U+2524C
U+2542E
U+254D9
U+255A7
U+257A9
U+257B4
U+259D4
U+25AE4
U+25AE3
U+25AF1
U+25BB2
U+25C4B
U+25C64
U+25E2E
U+25E56
U+25E65
U+25E62
U+25ED8
U+25EC2
U+25EE8
U+25F23
U+25F5C
U+25FE0
U+25FD4
U+2600C
U+25FFB
U+26017
U+26060
U+260ED
U+26270
U+26286
U+2634C
U+23D0E
U+26402
U+2667E
U+266B0
U+2671D
U+268DD
U+268EA
U+26951
U+2696F
U+269DD
U+26A1E
U+26A58
U+26A8C
U+26AB7
U+26C73
U+26CDD
U+26E65
U+26F94
U+26FF8
U+26FF6
U+26FF7
U+2710D
U+27139
U+273DB
U+273DA
U+273FE
U+27410
U+27449
U+27615
U+27614
U+27631
U+27693
U+2770E
U+27723
U+27752
U+27985
U+27A84
U+27BB3
U+27BBE
U+27BC7
U+27CB8
U+27DA0
U+27E10
U+27FB7
U+2808A
U+280BB
U+28282
U+282F3
U+2840C
U+28455
U+2856B
U+285C8
U+285C9
U+286D7
U+286FA
U+28949
U+28946
U+2896B
U+28987
U+28988
U+289BA
U+289BB
U+28A1E
U+28A29
U+28A71
U+28A43
U+28A99
U+28ACD
U+28AE4
U+28ADD
U+28BC1
U+28BEF
U+28D10
U+28D71
U+28DFB
U+28E1F
U+28E36
U+28E89
U+28EEB
U+28F32
U+28FF8
U+292A0
U+292B1
U+29490
U+295CF
U+2967F
U+296F0
U+29719
U+29750
U+298C6
U+29A72
U+29DDB
U+29E3D
U+29E15
U+29E8A
U+29E49
U+29EC4
U+29EE9
U+29EDB
U+29FCE
U+2A02F
U+2A01A
U+2A0F9
U+2A082
U+22218
U+2A38C
U+2A437
U+2A5F1
U+2A602
U+2A61A
U+2A6B2


上の一覧を読み込んで変換して出力します。
実行環境はmacosx上のeclipseです。コンソールに文字を出力してみます。

使ったコード
package a;

import java.io.BufferedInputStream;
import java.io.UnsupportedEncodingException;
import java.nio.ByteBuffer;
import java.util.Scanner;

public class TestUnicode_surrogatepair {

/**
* バイトの配列を16進数表現で標準出力するよ
* @param bs
*/
static void printHex(String title, byte[] bs) {
System.out.print(title + "[");
for (byte b : bs) {
System.out.printf("0x%H ", (int) b & 0xff);
}
System.out.println("]");
}

/**
* バイトの配列を16進数表現で標準出力するよ
* @param bs
*/
static void printHex(String title, char[] cs) {
System.out.print(title + "[");
for (char c : cs) {
System.out.printf("0x%H ", (int) c);
}
System.out.println("]");
}

static void printCodePoint(int codePoint) {
System.out.printf("Character:[%c]%n", codePoint);
}

/**
* intをバイト配列にします。
* @param a
* @return
*/
static byte[] bytes(int a) {
byte[] bs = new byte[4];
bs[3] = (byte) (0x000000ff & (a));
bs[2] = (byte) (0x000000ff & (a >> 8));
bs[1] = (byte) (0x000000ff & (a >> 16));
bs[0] = (byte) (0x000000ff & (a >> 24));
return bs;
}

/**
* バイトの配列をintにします。
* @param bs
* @return
*/
static int INT(byte[] bs) {
return ByteBuffer.wrap(bs).asIntBuffer().get();
}

/**
*
* @param bs1
* @param bs2
* @return
*/
static byte[] mergeLowerBytes(byte[] bs1, byte[] bs2) {
byte[] bs = new byte[4];

System.arraycopy(bs1, 2, bs, 0, 2);
System.arraycopy(bs2, 2, bs, 2, 2);
return bs;
}

/**
* コードポイントからサロゲートペアバイト配列にしてます。 チェック処理してない
* @param codepoint
* @return
*/
static byte[] surrogate(int codepoint) {
int c = codepoint;// 21bit
c -= 0x10000;
int c1 = (c >>> (10));// 10bit
int c2 = 0x3FF & c;// 10bit
byte[] high = bytes(c1 + 0xD800);
byte[] low = bytes(c2 + 0xDC00);
byte[] bs = mergeLowerBytes(high, low);
return bs;
}

/**
* サロゲート文字からコードポイントを求める。 チェック処理してない
*
* @param surrogate
* @return
*/
static int codepoint(int surrogate) {
int c = surrogate;// 32bit
// high
int high = 0xffff0000 & c;
int low = 0x0000ffff & c;
high >>>= 16;
high -= 0xD800;
low -= 0xDC00;
high <<= 10;
int merge = (high + low) + 0x10000;
return merge;
}

/**
* テストメイン
* @param args
* @throws UnsupportedEncodingException
*/
public static void main(String[] args) throws UnsupportedEncodingException {
a();
}

static void a() throws UnsupportedEncodingException {

{
BufferedInputStream source = new BufferedInputStream(
TestUnicode_surrogatepair.class
.getResourceAsStream("doc-files/surrogatepair.txt"));
Scanner scanner = new Scanner(source);

while (scanner.hasNext()) {
String line = scanner.nextLine();
String s = line.replaceFirst("U\\+", "");
int codepoint = Integer.parseInt(s, 16);
String s1 = new String(Character.toChars(codepoint));// Java API
String s2 = new String(surrogate(codepoint), "utf16");// オレオレ実装
printHex(s1 + ":" + s2 + ":", surrogate(codepoint));
}
}
}

}


実行結果
使用しているブラウザ、OS、設定フォントによっては化け化けだと思う...
��:��:[0xD8 0x40 0xDC 0xB ]
��:��:[0xD8 0x44 0xDE 0x3D ]
��:��:[0xD8 0x44 0xDF 0x1B ]
��:��:[0xD8 0x45 0xDC 0x6E ]
��:��:[0xD8 0x46 0xDC 0xBD ]
��:��:[0xD8 0x42 0xDF 0x9F ]
��:��:[0xD8 0x45 0xDE 0xB4 ]
��:��:[0xD8 0x47 0xDE 0x34 ]
��:��:[0xD8 0x4C 0xDD 0xC4 ]
��:��:[0xD8 0x4D 0xDD 0xC4 ]
��:��:[0xD8 0x4D 0xDF 0x3F ]
��:��:[0xD8 0x4D 0xDF 0x63 ]
��:��:[0xD8 0x4F 0xDC 0xFE ]
��:��:[0xD8 0x51 0xDF 0xF1 ]
��:��:[0xD8 0x55 0xDC 0x8E ]
��:��:[0xD8 0x55 0xDD 0xE ]
��:��:[0xD8 0x55 0xDF 0x71 ]
��:��:[0xD8 0x56 0xDD 0xC4 ]
��:��:[0xD8 0x57 0xDD 0xA1 ]
��:��:[0xD8 0x5A 0xDE 0xFF ]
��:��:[0xD8 0x5B 0xDE 0x40 ]
��:��:[0xD8 0x5C 0xDC 0xF4 ]
��:��:[0xD8 0x5D 0xDE 0x84 ]
��:��:[0xD8 0x60 0xDE 0x77 ]
��:��:[0xD8 0x60 0xDF 0xCD ]
��:��:[0xD8 0x68 0xDD 0x90 ]
��:��:[0xD8 0x40 0xDC 0x89 ]
��:��:[0xD8 0x40 0xDC 0xA2 ]
��:��:[0xD8 0x40 0xDC 0xA4 ]
��:��:[0xD8 0x40 0xDD 0xA2 ]
��:��:[0xD8 0x40 0xDE 0x13 ]
��:��:[0xD8 0x40 0xDF 0x2B ]
��:��:[0xD8 0x40 0xDF 0x81 ]
��:��:[0xD8 0x40 0xDF 0x71 ]
��:��:[0xD8 0x40 0xDF 0xF9 ]
��:��:[0xD8 0x41 0xDC 0x4A ]
��:��:[0xD8 0x41 0xDD 0x9 ]
��:��:[0xD8 0x41 0xDD 0xD6 ]
��:��:[0xD8 0x41 0xDE 0x28 ]
��:��:[0xD8 0x41 0xDF 0x4F ]
��:��:[0xD8 0x42 0xDC 0x7 ]
��:��:[0xD8 0x42 0xDC 0x3A ]
��:��:[0xD8 0x42 0xDC 0xB9 ]
��:��:[0xD8 0x42 0xDD 0x7C ]
��:��:[0xD8 0x42 0xDD 0x9D ]
��:��:[0xD8 0x42 0xDE 0xD3 ]
��:��:[0xD8 0x42 0xDF 0x1D ]
��:��:[0xD8 0x43 0xDD 0x45 ]
��:��:[0xD8 0x43 0xDD 0xE1 ]
��:��:[0xD8 0x43 0xDE 0x95 ]
��:��:[0xD8 0x43 0xDE 0x6D ]
��:��:[0xD8 0x43 0xDE 0x64 ]
��:��:[0xD8 0x43 0xDF 0x5F ]
��:��:[0xD8 0x44 0xDE 0x1 ]
��:��:[0xD8 0x44 0xDE 0x55 ]
��:��:[0xD8 0x44 0xDE 0x7B ]
��:��:[0xD8 0x44 0xDE 0x74 ]
��:��:[0xD8 0x44 0xDE 0xE4 ]
��:��:[0xD8 0x44 0xDE 0xD7 ]
��:��:[0xD8 0x44 0xDE 0xFD ]
��:��:[0xD8 0x44 0xDF 0x36 ]
��:��:[0xD8 0x44 0xDF 0x44 ]
��:��:[0xD8 0x44 0xDF 0xC4 ]
��:��:[0xD8 0x45 0xDC 0x6D ]
��:��:[0xD8 0x45 0xDD 0xD7 ]
��:��:[0xD8 0x5B 0xDC 0x29 ]
��:��:[0xD8 0x45 0xDE 0x47 ]
��:��:[0xD8 0x45 0xDF 0x6 ]
��:��:[0xD8 0x45 0xDF 0x42 ]
��:��:[0xD8 0x46 0xDD 0xC3 ]
��:��:[0xD8 0x47 0xDC 0x56 ]
��:��:[0xD8 0x47 0xDD 0x2D ]
��:��:[0xD8 0x47 0xDD 0x45 ]
��:��:[0xD8 0x47 0xDD 0x78 ]
��:��:[0xD8 0x47 0xDD 0x62 ]
��:��:[0xD8 0x47 0xDD 0xA1 ]
��:��:[0xD8 0x47 0xDD 0x9C ]
��:��:[0xD8 0x47 0xDD 0x92 ]
��:��:[0xD8 0x47 0xDD 0xB7 ]
��:��:[0xD8 0x47 0xDD 0xE0 ]
��:��:[0xD8 0x47 0xDE 0x33 ]
��:��:[0xD8 0x47 0xDF 0x1E ]
��:��:[0xD8 0x47 0xDF 0x76 ]
��:��:[0xD8 0x47 0xDF 0xFA ]
��:��:[0xD8 0x48 0xDD 0x7B ]
��:��:[0xD8 0x48 0xDF 0x1E ]
��:��:[0xD8 0x48 0xDF 0xAD ]
��:��:[0xD8 0x49 0xDE 0xF3 ]
��:��:[0xD8 0x4A 0xDC 0x5B ]
��:��:[0xD8 0x4A 0xDC 0xAB ]
��:��:[0xD8 0x4A 0xDD 0x8F ]
��:��:[0xD8 0x4A 0xDE 0xB8 ]
��:��:[0xD8 0x4A 0xDF 0x4F ]
��:��:[0xD8 0x4A 0xDF 0x50 ]
��:��:[0xD8 0x4A 0xDF 0x46 ]
��:��:[0xD8 0x4B 0xDC 0x1D ]
��:��:[0xD8 0x4A 0xDF 0xA6 ]
��:��:[0xD8 0x4B 0xDC 0x24 ]
��:��:[0xD8 0x4B 0xDD 0xE1 ]
��:��:[0xD8 0x4C 0xDD 0xC3 ]
��:��:[0xD8 0x4C 0xDD 0xF5 ]
��:��:[0xD8 0x4C 0xDD 0xB6 ]
��:��:[0xD8 0x4C 0xDF 0x72 ]
��:��:[0xD8 0x4C 0xDF 0xD3 ]
��:��:[0xD8 0x4C 0xDF 0xD2 ]
��:��:[0xD8 0x4C 0xDF 0xD0 ]
��:��:[0xD8 0x4C 0xDF 0xE4 ]
��:��:[0xD8 0x4C 0xDF 0xD5 ]
��:��:[0xD8 0x4C 0xDF 0xDA ]
��:��:[0xD8 0x4C 0xDF 0xDF ]
��:��:[0xD8 0x4D 0xDC 0x4A ]
��:��:[0xD8 0x4D 0xDC 0x51 ]
��:��:[0xD8 0x4D 0xDC 0x4B ]
��:��:[0xD8 0x4D 0xDC 0x65 ]
��:��:[0xD8 0x4D 0xDC 0xE4 ]
��:��:[0xD8 0x4D 0xDD 0x5A ]
��:��:[0xD8 0x4D 0xDD 0x94 ]
��:��:[0xD8 0x4D 0xDE 0x39 ]
��:��:[0xD8 0x4D 0xDE 0x47 ]
��:��:[0xD8 0x4D 0xDE 0x38 ]
��:��:[0xD8 0x4D 0xDE 0x3A ]
��:��:[0xD8 0x4D 0xDF 0x1C ]
��:��:[0xD8 0x4D 0xDF 0xC ]
��:��:[0xD8 0x4D 0xDF 0x64 ]
��:��:[0xD8 0x4D 0xDF 0xFF ]
��:��:[0xD8 0x4D 0xDF 0xE7 ]
��:��:[0xD8 0x4E 0xDC 0x24 ]
��:��:[0xD8 0x4E 0xDC 0x3D ]
��:��:[0xD8 0x4E 0xDE 0x98 ]
��:��:[0xD8 0x4F 0xDC 0x7F ]
��:��:[0xD8 0x4F 0xDD 0x0 ]
��:��:[0xD8 0x4F 0xDD 0x40 ]
��:��:[0xD8 0x4F 0xDD 0xFA ]
��:��:[0xD8 0x4F 0xDD 0xF9 ]
��:��:[0xD8 0x4F 0xDD 0xD3 ]
��:��:[0xD8 0x4F 0xDF 0x7E ]
��:��:[0xD8 0x50 0xDC 0x96 ]
��:��:[0xD8 0x50 0xDD 0x3 ]
��:��:[0xD8 0x50 0xDD 0xC6 ]
��:��:[0xD8 0x50 0xDD 0xFE ]
��:��:[0xD8 0x50 0xDF 0xBC ]
��:��:[0xD8 0x51 0xDE 0x29 ]
��:��:[0xD8 0x51 0xDE 0xA5 ]
��:��:[0xD8 0x52 0xDC 0x96 ]
��:��:[0xD8 0x52 0xDE 0x4D ]
��:��:[0xD8 0x52 0xDF 0x56 ]
��:��:[0xD8 0x52 0xDF 0x6F ]
��:��:[0xD8 0x53 0xDC 0x16 ]
��:��:[0xD8 0x53 0xDD 0x14 ]
��:��:[0xD8 0x53 0xDE 0xE ]
��:��:[0xD8 0x53 0xDE 0x37 ]
��:��:[0xD8 0x53 0xDE 0x6A ]
��:��:[0xD8 0x53 0xDE 0x8B ]
��:��:[0xD8 0x54 0xDC 0x4A ]
��:��:[0xD8 0x54 0xDC 0x55 ]
��:��:[0xD8 0x54 0xDD 0x22 ]
��:��:[0xD8 0x54 0xDD 0xA9 ]
��:��:[0xD8 0x54 0xDD 0xE5 ]
��:��:[0xD8 0x54 0xDD 0xCD ]
��:��:[0xD8 0x54 0xDE 0x1E ]
��:��:[0xD8 0x54 0xDE 0x4C ]
��:��:[0xD8 0x55 0xDC 0x2E ]
��:��:[0xD8 0x55 0xDC 0xD9 ]
��:��:[0xD8 0x55 0xDD 0xA7 ]
��:��:[0xD8 0x55 0xDF 0xA9 ]
��:��:[0xD8 0x55 0xDF 0xB4 ]
��:��:[0xD8 0x56 0xDD 0xD4 ]
��:��:[0xD8 0x56 0xDE 0xE4 ]
��:��:[0xD8 0x56 0xDE 0xE3 ]
��:��:[0xD8 0x56 0xDE 0xF1 ]
��:��:[0xD8 0x56 0xDF 0xB2 ]
��:��:[0xD8 0x57 0xDC 0x4B ]
��:��:[0xD8 0x57 0xDC 0x64 ]
��:��:[0xD8 0x57 0xDE 0x2E ]
��:��:[0xD8 0x57 0xDE 0x56 ]
��:��:[0xD8 0x57 0xDE 0x65 ]
��:��:[0xD8 0x57 0xDE 0x62 ]
��:��:[0xD8 0x57 0xDE 0xD8 ]
��:��:[0xD8 0x57 0xDE 0xC2 ]
��:��:[0xD8 0x57 0xDE 0xE8 ]
��:��:[0xD8 0x57 0xDF 0x23 ]
��:��:[0xD8 0x57 0xDF 0x5C ]
��:��:[0xD8 0x57 0xDF 0xE0 ]
��:��:[0xD8 0x57 0xDF 0xD4 ]
��:��:[0xD8 0x58 0xDC 0xC ]
��:��:[0xD8 0x57 0xDF 0xFB ]
��:��:[0xD8 0x58 0xDC 0x17 ]
��:��:[0xD8 0x58 0xDC 0x60 ]
��:��:[0xD8 0x58 0xDC 0xED ]
��:��:[0xD8 0x58 0xDE 0x70 ]
��:��:[0xD8 0x58 0xDE 0x86 ]
��:��:[0xD8 0x58 0xDF 0x4C ]
��:��:[0xD8 0x4F 0xDD 0xE ]
��:��:[0xD8 0x59 0xDC 0x2 ]
��:��:[0xD8 0x59 0xDE 0x7E ]
��:��:[0xD8 0x59 0xDE 0xB0 ]
��:��:[0xD8 0x59 0xDF 0x1D ]
��:��:[0xD8 0x5A 0xDC 0xDD ]
��:��:[0xD8 0x5A 0xDC 0xEA ]
��:��:[0xD8 0x5A 0xDD 0x51 ]
��:��:[0xD8 0x5A 0xDD 0x6F ]
��:��:[0xD8 0x5A 0xDD 0xDD ]
��:��:[0xD8 0x5A 0xDE 0x1E ]
��:��:[0xD8 0x5A 0xDE 0x58 ]
��:��:[0xD8 0x5A 0xDE 0x8C ]
��:��:[0xD8 0x5A 0xDE 0xB7 ]
��:��:[0xD8 0x5B 0xDC 0x73 ]
��:��:[0xD8 0x5B 0xDC 0xDD ]
��:��:[0xD8 0x5B 0xDE 0x65 ]
��:��:[0xD8 0x5B 0xDF 0x94 ]
��:��:[0xD8 0x5B 0xDF 0xF8 ]
��:��:[0xD8 0x5B 0xDF 0xF6 ]
��:��:[0xD8 0x5B 0xDF 0xF7 ]
��:��:[0xD8 0x5C 0xDD 0xD ]
��:��:[0xD8 0x5C 0xDD 0x39 ]
��:��:[0xD8 0x5C 0xDF 0xDB ]
��:��:[0xD8 0x5C 0xDF 0xDA ]
��:��:[0xD8 0x5C 0xDF 0xFE ]
��:��:[0xD8 0x5D 0xDC 0x10 ]
��:��:[0xD8 0x5D 0xDC 0x49 ]
��:��:[0xD8 0x5D 0xDE 0x15 ]
��:��:[0xD8 0x5D 0xDE 0x14 ]
��:��:[0xD8 0x5D 0xDE 0x31 ]
��:��:[0xD8 0x5D 0xDE 0x93 ]
��:��:[0xD8 0x5D 0xDF 0xE ]
��:��:[0xD8 0x5D 0xDF 0x23 ]
��:��:[0xD8 0x5D 0xDF 0x52 ]
��:��:[0xD8 0x5E 0xDD 0x85 ]
��:��:[0xD8 0x5E 0xDE 0x84 ]
��:��:[0xD8 0x5E 0xDF 0xB3 ]
��:��:[0xD8 0x5E 0xDF 0xBE ]
��:��:[0xD8 0x5E 0xDF 0xC7 ]
��:��:[0xD8 0x5F 0xDC 0xB8 ]
��:��:[0xD8 0x5F 0xDD 0xA0 ]
��:��:[0xD8 0x5F 0xDE 0x10 ]
��:��:[0xD8 0x5F 0xDF 0xB7 ]
��:��:[0xD8 0x60 0xDC 0x8A ]
��:��:[0xD8 0x60 0xDC 0xBB ]
��:��:[0xD8 0x60 0xDE 0x82 ]
��:��:[0xD8 0x60 0xDE 0xF3 ]
��:��:[0xD8 0x61 0xDC 0xC ]
��:��:[0xD8 0x61 0xDC 0x55 ]
��:��:[0xD8 0x61 0xDD 0x6B ]
��:��:[0xD8 0x61 0xDD 0xC8 ]
��:��:[0xD8 0x61 0xDD 0xC9 ]
��:��:[0xD8 0x61 0xDE 0xD7 ]
��:��:[0xD8 0x61 0xDE 0xFA ]
��:��:[0xD8 0x62 0xDD 0x49 ]
��:��:[0xD8 0x62 0xDD 0x46 ]
��:��:[0xD8 0x62 0xDD 0x6B ]
��:��:[0xD8 0x62 0xDD 0x87 ]
��:��:[0xD8 0x62 0xDD 0x88 ]
��:��:[0xD8 0x62 0xDD 0xBA ]
��:��:[0xD8 0x62 0xDD 0xBB ]
��:��:[0xD8 0x62 0xDE 0x1E ]
��:��:[0xD8 0x62 0xDE 0x29 ]
��:��:[0xD8 0x62 0xDE 0x71 ]
��:��:[0xD8 0x62 0xDE 0x43 ]
��:��:[0xD8 0x62 0xDE 0x99 ]
��:��:[0xD8 0x62 0xDE 0xCD ]
��:��:[0xD8 0x62 0xDE 0xE4 ]
��:��:[0xD8 0x62 0xDE 0xDD ]
��:��:[0xD8 0x62 0xDF 0xC1 ]
��:��:[0xD8 0x62 0xDF 0xEF ]
��:��:[0xD8 0x63 0xDD 0x10 ]
��:��:[0xD8 0x63 0xDD 0x71 ]
��:��:[0xD8 0x63 0xDD 0xFB ]
��:��:[0xD8 0x63 0xDE 0x1F ]
��:��:[0xD8 0x63 0xDE 0x36 ]
��:��:[0xD8 0x63 0xDE 0x89 ]
��:��:[0xD8 0x63 0xDE 0xEB ]
��:��:[0xD8 0x63 0xDF 0x32 ]
��:��:[0xD8 0x63 0xDF 0xF8 ]
��:��:[0xD8 0x64 0xDE 0xA0 ]
��:��:[0xD8 0x64 0xDE 0xB1 ]
��:��:[0xD8 0x65 0xDC 0x90 ]
��:��:[0xD8 0x65 0xDD 0xCF ]
��:��:[0xD8 0x65 0xDE 0x7F ]
��:��:[0xD8 0x65 0xDE 0xF0 ]
��:��:[0xD8 0x65 0xDF 0x19 ]
��:��:[0xD8 0x65 0xDF 0x50 ]
��:��:[0xD8 0x66 0xDC 0xC6 ]
��:��:[0xD8 0x66 0xDE 0x72 ]
��:��:[0xD8 0x67 0xDD 0xDB ]
��:��:[0xD8 0x67 0xDE 0x3D ]
��:��:[0xD8 0x67 0xDE 0x15 ]
��:��:[0xD8 0x67 0xDE 0x8A ]
��:��:[0xD8 0x67 0xDE 0x49 ]
��:��:[0xD8 0x67 0xDE 0xC4 ]
��:��:[0xD8 0x67 0xDE 0xE9 ]
��:��:[0xD8 0x67 0xDE 0xDB ]
��:��:[0xD8 0x67 0xDF 0xCE ]
��:��:[0xD8 0x68 0xDC 0x2F ]
��:��:[0xD8 0x68 0xDC 0x1A ]
��:��:[0xD8 0x68 0xDC 0xF9 ]
��:��:[0xD8 0x68 0xDC 0x82 ]
��:��:[0xD8 0x48 0xDE 0x18 ]
��:��:[0xD8 0x68 0xDF 0x8C ]
��:��:[0xD8 0x69 0xDC 0x37 ]
��:��:[0xD8 0x69 0xDD 0xF1 ]
��:��:[0xD8 0x69 0xDE 0x2 ]
��:��:[0xD8 0x69 0xDE 0x1A ]
��:��:[0xD8 0x69 0xDE 0xB2 ]




[java]サロゲートペアからコードポイントをもとめる


Javaです。文字です。ユニコードです。えーとサロゲートペアとコードポイントです。
コード書いて手を動かさないといまいちイメージがわかないんですよね。ということでサロゲートペアのデータからコードポイントを求めるのと、その逆を行ってみます。
この記事はmacosx上のJava1.6を使用したものをベースとしてます。

javaの用意されているapiを使うのと、自分実装です。

参考



サロゲートペアとは、BMPの中の文字の割り当てのない符号位置2つを用いて、BMP外の面の符号位置を指すものです。プログラマのための文字コード技術入門 (WEB+DB PRESS plus) (WEB+DB PRESS plusシリーズ)


この本一人一冊で!!
プログラマのための文字コード技術入門 (WEB+DB PRESS plus) (WEB+DB PRESS plusシリーズ)
矢野 啓介
477414164X

実装
/**
* コードポイントからサロゲートペアバイト配列にしてます。
* チェック処理してない
* @param codepoint
* @return
*/
static byte[] surrogate(int codepoint) {
int c = codepoint;// 21bit
c -= 0x10000;
int c1 = (c >>> (10));// 10bit
int c2 = 0x3FF & c;// 10bit
byte[] high = bytes(c1 + 0xD800);
byte[] low = bytes(c2 + 0xDC00);
byte[] bs = mergeLowerBytes(high, low);
return bs;
}

/**
* サロゲート文字からコードポイントを求める。
* チェック処理してない
* @param surrogate
* @return
*/
static int codepoint(int surrogate) {
int c = surrogate;// 32bit
// high
int high = 0xffff0000 & c;
int low = 0x0000ffff & c;
high >>>= 16;
high -= 0xD800;
low -= 0xDC00;
high <<= 10;
int merge = (high + low) + 0x10000;
return merge;
}




長いけどソース

実行結果は


package a;

import java.nio.ByteBuffer;

public class TestUnicode_surrogatepair {

/**
* バイトの配列を16進数表現で標準出力するよ
* @param bs
*/
static void printHex(String title, byte[] bs) {
System.out.print(title+"[");
for (byte b : bs) {
System.out.printf("0x%H ", (int) b & 0xff);
}
System.out.println("]");
}

/**
* バイトの配列を16進数表現で標準出力するよ
* @param bs
*/
static void printHex(String title, char[] cs) {
System.out.print(title+"[");
for (char c : cs) {
System.out.printf("0x%H ", (int) c);
}
System.out.println("]");
}

static void printCodePoint(int codePoint){
System.out.printf("Character:[%c]%n", codePoint);
}

/**
* intをバイト配列にします。
* @param a
* @return
*/
static byte[] bytes(int a) {
byte[] bs = new byte[4];
bs[3] = (byte) (0x000000ff & (a));
bs[2] = (byte) (0x000000ff & (a >> 8));
bs[1] = (byte) (0x000000ff & (a >> 16));
bs[0] = (byte) (0x000000ff & (a >> 24));
return bs;
}

/**
* バイトの配列をintにします。
* @param bs
* @return
*/
static int INT(byte[] bs) {
return ByteBuffer.wrap(bs).asIntBuffer().get();
}


/**
*
* @param bs1
* @param bs2
* @return
*/
static byte[] mergeLowerBytes(byte[] bs1, byte[] bs2) {
byte[] bs = new byte[4];

System.arraycopy(bs1, 2, bs, 0, 2);
System.arraycopy(bs2, 2, bs, 2, 2);
return bs;
}

/**
* コードポイントからサロゲートペアバイト配列にしてます。
* チェック処理してない
* @param codepoint
* @return
*/
static byte[] surrogate(int codepoint) {
int c = codepoint;// 21bit

c -= 0x10000;
int c1 = (c >>> (10));// 10bit
int c2 = 0x3FF & c;// 10bit

byte[] high = bytes(c1 + 0xD800);
byte[] low = bytes(c2 + 0xDC00);

byte[] bs = mergeLowerBytes(high, low);
return bs;
}

/**
* サロゲート文字からコードポイントを求める。
* チェック処理してない
* @param surrogate
* @return
*/
static int codepoint(int surrogate) {
int c = surrogate;// 32bit
// high
int high = 0xffff0000 & c;
int low = 0x0000ffff & c;

high >>>= 16;
high -= 0xD800;
low -= 0xDC00;

high <<= 10;

int merge = (high + low) + 0x10000;
return merge;
}

/**
* テストメイン
*
*
* @param args
*/
public static void main(String[] args) {
a();
}

static void a() {
// (1)Javaですでに用意されてるAPIを使ってみる
// (2)自分実装で変換してみる

// サロゲートペア文字
int c = 0xD867DE15;
char[] CS ={0xD867, 0xDE15};
{
/*
* (1)
*/
// コードポイント
int codepoint = Character.toCodePoint(CS[0], CS[1]);
System.out.printf("codepoint:[u+%h]%n", codepoint);
printCodePoint(codepoint);
// コードポイントからutf-16配列を得る
char[] cs = Character.toChars(codepoint);
printHex("UTF-16:", cs);
}
System.out.println("====================");
{
/*
* (2)
*/
int codepoint = codepoint(c);
System.out.printf("codepoint:[u+%h]%n", codepoint);
printCodePoint(codepoint);
byte[] bs = surrogate(codepoint);
printHex("UTF-16:", bs);

}
}

}




2010-11-12

文字化け覚悟


Javaです。文字化け覚悟です。
文字化けというより表示されないかもですかね。

プログラマのための文字コード技術入門 (WEB+DB PRESS plus) (WEB+DB PRESS plusシリーズ)
矢野 啓介
477414164X


上記の本のp237にサロゲートと結合文字がのっています。

package a;

import java.io.UnsupportedEncodingException;
import java.nio.ByteBuffer;

public class A {

/**
* バイトの配列を16進数表現で標準出力します。
*
* @param bs
*/
static void printHex(byte[] bs) {
for (byte b : bs) {
int i = (int) b;
String s = String.format("%h", 0x00000000ff & i).toUpperCase();
System.out.print((s.length() < 2 ? "0" : "") + s + " ");
}
System.out.println();
}

/**
* intをバイト配列にします。
*
* @param a
* @return
*/
static byte[] toBytes(int a) {
byte[] bs = new byte[4];
bs[3] = (byte) (0x000000ff & (a));
bs[2] = (byte) (0x000000ff & (a >> 8));
bs[1] = (byte) (0x000000ff & (a >> 16));
bs[0] = (byte) (0x000000ff & (a >> 24));
return bs;
}

/**
* バイトの配列をintにします。
*
* @param bs
* @return
*/
static int toInt(byte[] bs) {
return ByteBuffer.wrap(bs).asIntBuffer().get();
}

/**
* バイトの配列を結合していきます。
*
* @param top
* @param bs
* @param bottom
* @return
*/
static byte[] sandwich(byte[] top, byte[] bs, byte[] bottom) {
byte[] ret = new byte[top.length + bs.length + bottom.length];
int[] pos = { 0, top.length, top.length + bs.length };
System.arraycopy(top, 0, ret, pos[0], top.length);
System.arraycopy(bs, 0, ret, pos[1], bs.length);
System.arraycopy(bottom, 0, ret, pos[2], bottom.length);
return ret;
}

public static void main(String[] args) throws UnsupportedEncodingException {
a();
}

static void print(int i, String characterset)
throws UnsupportedEncodingException {
byte[] bs = toBytes(i);
print(bs, characterset);
}

static void print(byte[] bs, String characterset)
throws UnsupportedEncodingException {
String s = new String(bs, characterset);
System.out.println(characterset + ":" + s);
}

static void a() throws UnsupportedEncodingException {
{

// これは結合文字です。
print(0x304B309A, "utf16");
// サロゲート文字です。
print(0xD867DE15, "utf16");
}

}

}


結果
実行はmac osx上のeclipseです。
コンソールにでたものをキャプチャしました。






文字コードのための手習いその2


Javaです。文字コードのための手習いその2です。

まずこちらにある対応表をベースに実験です。



package a;

import java.io.UnsupportedEncodingException;
import java.nio.ByteBuffer;

public class A {

/**
* バイトの配列を16進数表現で標準出力します。
*
* @param bs
*/
static void printHex(byte[] bs) {
for (byte b : bs) {
int i = (int) b;
String s = String.format("%h", 0x00000000ff & i).toUpperCase();
System.out.print((s.length() < 2 ? "0" : "") + s + " ");
}
System.out.println();
}

/**
* intをバイト配列にします。
*
* @param a
* @return
*/
static byte[] toBytes(int a) {
byte[] bs = new byte[4];
bs[3] = (byte) (0x000000ff & (a));
bs[2] = (byte) (0x000000ff & (a >> 8));
bs[1] = (byte) (0x000000ff & (a >> 16));
bs[0] = (byte) (0x000000ff & (a >> 24));
return bs;
}

/**
* バイトの配列をintにします。
*
* @param bs
* @return
*/
static int toInt(byte[] bs) {
return ByteBuffer.wrap(bs).asIntBuffer().get();
}

/**
* バイトの配列を結合していきます。
*
* @param top
* @param bs
* @param bottom
* @return
*/
static byte[] sandwich(byte[] top, byte[] bs, byte[] bottom) {
byte[] ret = new byte[top.length + bs.length + bottom.length];
int[] pos = { 0, top.length, top.length + bs.length };
System.arraycopy(top, 0, ret, pos[0], top.length);
System.arraycopy(bs, 0, ret, pos[1], bs.length);
System.arraycopy(bottom, 0, ret, pos[2], bottom.length);
return ret;
}

public static void main(String[] args) throws UnsupportedEncodingException {
a();
}

static void print(int i, String characterset)
throws UnsupportedEncodingException {
byte[] bs = toBytes(i);
print(bs, characterset);
}

static void print(byte[] bs, String characterset)
throws UnsupportedEncodingException {
String s = new String(bs, characterset);
System.out.println(characterset + ":" + s);
}

static void a() throws UnsupportedEncodingException {
{
System.out.println("♂♀");

// Shift_JIS-2004 (JIS X 0213:2004 Appendix 1) vs Unicode mapping
// tableより
// 0x8189 U+2642 # MALE SIGN
// 0x818A U+2640 # FEMALE SIGN
print(0x8189, "sjis");
print(0x818A, "sjis");

// EUC-JIS-2004 (JIS X 0213:2004 Appendix 3) vs Unicode mapping
// tableより
// 0xA1E9 U+2642 # MALE SIGN
// 0xA1EA U+2640 # FEMALE SIGN
print(0xA1E9, "EUC_JP_LINUX");
print(0xA1EA, "EUC_JP_LINUX");

// ISO-2022-JP-2004 vs Unicode mapping tableより
// 3-2169 U+2642 # MALE SIGN
// 3-216A U+2640 # FEMALE SIGN
print(sandwich(new byte[] { 0x1B, 0x24, 0x42 }, new byte[] { 0x21,
0x69 }, new byte[] { 0x1B, 0x28, 0x42 }), "ISO2022JP");
print(sandwich(new byte[] { 0x1B, 0x24, 0x42 }, new byte[] { 0x21,
0x6A }, new byte[] { 0x1B, 0x28, 0x42 }), "ISO2022JP");

// 最後にunicode
print(0x2642, "utf16");
print(0x2640, "utf16");

// String s = "♂";
// byte[] bs = s.getBytes("ISO2022JP");
// printHex(bs);
// System.out.println(new String(bs, "ISO2022JP"));
}

}

}


結果

♂♀
sjis:♂
sjis:♀
EUC_JP_LINUX:♂
EUC_JP_LINUX:♀
ISO2022JP:♂
ISO2022JP:♀
utf16:♂
utf16:♀




[java]intをbyteの配列にする


javaです。

intの値をbyteの配列にします。
あと、byteの配列からintの値にします。


import java.nio.ByteBuffer;

public class A {

/**
* バイトの配列を16進数表現で標準出力します。
*
* @param bs
*/
static void printHex(byte[] bs) {
for (byte b : bs) {
int i = (int) b;
String s = String.format("%h", 0x00000000ff & i).toUpperCase();
System.out.print((s.length() < 2 ? "0" : "") + s + " ");
}
System.out.println();
}

/**
* intをバイト配列にします。
*
* @param a
* @return
*/
static byte[] toBytes(int a) {
byte[] bs = new byte[4];
bs[3] = (byte) (0x000000ff & (a));
bs[2] = (byte) (0x000000ff & (a >>> 8));
bs[1] = (byte) (0x000000ff & (a >>> 16));
bs[0] = (byte) (0x000000ff & (a >>> 24));
return bs;
}

/**
* バイトの配列をintにします。
*
* @param bs
* @return
*/
static int toInt(byte[] bs) {
return ByteBuffer.wrap(bs).asIntBuffer().get();
}

public static void main(String[] args) {
a();
}

static void a() {
{
byte[] bs = toBytes(Integer.MAX_VALUE);
printHex(bs);
int i = toInt(bs);
if (i == Integer.MAX_VALUE) {
System.out.println("*** OK");
} else {
System.err.println("*** ouach!!");
}
}

{
byte[] bs = toBytes(Integer.MIN_VALUE);
printHex(bs);
int i = toInt(bs);
if (i == Integer.MIN_VALUE) {
System.out.println("*** OK");
} else {
System.err.println("*** ouach!!");
}
}
}

}


動かした結果
7F FF FF FF
*** OK
80 00 00 00
*** OK




2010-11-11

[java]Integer.MAX_VALUEに1を足してみたら


Javaです。

同じまちがいをおこすということは、きっとそのまちがいが自分の根っこの部分にマッチしているからなのだなーと思う今日この頃です。

Integer.MAX_VALUEに1を加算するといったいどんな値になるのでしょうか?


試してみましょう。
public class A {

public static void main(String[] args) {
a();
b();
}

static void a(){
int i = Integer.MAX_VALUE + 1;
System.out.println(i);
System.out.println(Integer.MIN_VALUE);
}
static void b(){
int i = Integer.MIN_VALUE - 1;
System.out.println(i);
System.out.println(Integer.MAX_VALUE);
}
}


-2147483648
-2147483648
2147483647
2147483647


結果は、Integer.MIN_VALUEとなります。
同じようにInteger.MIN_VALUE - 1してみますと、Integer.MAX_VALUEとなります。

循環しているのですね。

あっ、既視感(déjà-vu).....

関連
プログラマメモ2: java 2の31乗とInteger.MAX_VALUE




 

プログラマの本棚