GB2312轉(zhuǎn)換為UTF-8
摩托羅拉的部分手機(jī)(a1200,e60等),不支持gb2312編碼。曾經(jīng)給我造成了不少麻煩。現(xiàn)在,大家可以分享解決這個(gè)問題的一些經(jīng)驗(yàn)。
關(guān)于gb2312,unicode,utf-8的一些資料,大家請(qǐng)自行搜索。一下列舉幾個(gè)比較好的資源網(wǎng)址。
http://baike.baidu.com/view/25492.htm
http://www.utf.com.cn/article/s45
http://www.utf.com.cn/article/s74
http://www.haiyan.com/steelk/navigator/ref/gb2312/gbindex.htm
要點(diǎn):
1,gb2312于unicode或者utf-8之間并不存在直接的映射關(guān)系。所以我們只能通過查表法來進(jìn)行轉(zhuǎn)換。
2,utf-8是unicode用于網(wǎng)絡(luò)傳輸?shù)囊环N形式,它與unicode之間是可以通過運(yùn)算來進(jìn)行轉(zhuǎn)換的。
3,j2me環(huán)境使用的都是utf-8編碼,但是請(qǐng)注意,j2me中的utf-8編碼比較特殊,在整個(gè)編碼前面對(duì)了兩個(gè)字節(jié),用于存放字符串的長(zhǎng)度。
過程:
1,制作映射表gb2312-unicode,應(yīng)為漢字的unicode比utf-8要小,這樣做出的表也會(huì)小一些,而且對(duì)于unicode的可擴(kuò)展性也強(qiáng)一些。
2,先將gb2312編碼串通過查表,轉(zhuǎn)換為unicode。
3,然后通過運(yùn)算,將unicode轉(zhuǎn)換為utf-8,以便在j2me環(huán)境下使用。
我修改了Herong Yang大俠的一個(gè)映射表生成函數(shù),原文請(qǐng)參考http://www.herongyang.com/gb2312/gb2312_unicode.html
它的作用是生成一個(gè)二進(jìn)制的gb2312到unicode的查找表,它按照gb2312的分區(qū),分塊特性,將其對(duì)應(yīng)的unicode按順序存入指定的位置。
這樣我們只需要根據(jù)gb2312的編碼,計(jì)算出索引就可以獲取編碼對(duì)應(yīng)的unicode了。
由于是修改的代碼,沒臉貼出來,大家有需求可以直接參考Herong Yang的文章,然后根據(jù)自己需求修改并生成自己的映射表。
這里我把自己這個(gè)轉(zhuǎn)換表文件以及訪問代碼公開。
http://download.csdn.net/source/263609
轉(zhuǎn)帖請(qǐng)注明。這是個(gè)傻瓜化的代碼,在java中給它gb2312的byte數(shù)組,它就給你構(gòu)造出字符串。
用在不支持gb2312的手機(jī)上非常方便。這個(gè)轉(zhuǎn)換表的大小是15228byte,對(duì)j2me來說還是可以接受的。
如果有朋友需要溝通,可以發(fā)郵件到hunhun1981@hotmail.com
關(guān)于gb2312,unicode,utf-8的一些資料,大家請(qǐng)自行搜索。一下列舉幾個(gè)比較好的資源網(wǎng)址。
http://baike.baidu.com/view/25492.htm
http://www.utf.com.cn/article/s45
http://www.utf.com.cn/article/s74
http://www.haiyan.com/steelk/navigator/ref/gb2312/gbindex.htm
要點(diǎn):
1,gb2312于unicode或者utf-8之間并不存在直接的映射關(guān)系。所以我們只能通過查表法來進(jìn)行轉(zhuǎn)換。
2,utf-8是unicode用于網(wǎng)絡(luò)傳輸?shù)囊环N形式,它與unicode之間是可以通過運(yùn)算來進(jìn)行轉(zhuǎn)換的。
3,j2me環(huán)境使用的都是utf-8編碼,但是請(qǐng)注意,j2me中的utf-8編碼比較特殊,在整個(gè)編碼前面對(duì)了兩個(gè)字節(jié),用于存放字符串的長(zhǎng)度。
過程:
1,制作映射表gb2312-unicode,應(yīng)為漢字的unicode比utf-8要小,這樣做出的表也會(huì)小一些,而且對(duì)于unicode的可擴(kuò)展性也強(qiáng)一些。
2,先將gb2312編碼串通過查表,轉(zhuǎn)換為unicode。
3,然后通過運(yùn)算,將unicode轉(zhuǎn)換為utf-8,以便在j2me環(huán)境下使用。
我修改了Herong Yang大俠的一個(gè)映射表生成函數(shù),原文請(qǐng)參考http://www.herongyang.com/gb2312/gb2312_unicode.html
它的作用是生成一個(gè)二進(jìn)制的gb2312到unicode的查找表,它按照gb2312的分區(qū),分塊特性,將其對(duì)應(yīng)的unicode按順序存入指定的位置。
這樣我們只需要根據(jù)gb2312的編碼,計(jì)算出索引就可以獲取編碼對(duì)應(yīng)的unicode了。
由于是修改的代碼,沒臉貼出來,大家有需求可以直接參考Herong Yang的文章,然后根據(jù)自己需求修改并生成自己的映射表。
這里我把自己這個(gè)轉(zhuǎn)換表文件以及訪問代碼公開。
http://download.csdn.net/source/263609
轉(zhuǎn)帖請(qǐng)注明。這是個(gè)傻瓜化的代碼,在java中給它gb2312的byte數(shù)組,它就給你構(gòu)造出字符串。
用在不支持gb2312的手機(jī)上非常方便。這個(gè)轉(zhuǎn)換表的大小是15228byte,對(duì)j2me來說還是可以接受的。
如果有朋友需要溝通,可以發(fā)郵件到hunhun1981@hotmail.com
import java.io.InputStream;
public class HGB2312 {
private byte[] map = new byte[15228];
private byte[] buffer;
private int index;
public HGB2312() throws Exception {
InputStream is = getClass().getResourceAsStream("/gb2u.dat");
is.read(map);
is.close();
}
public String gb2utf8(byte[] gb) throws Exception {
buffer = new byte[gb.length + gb.length / 2 + 3];
index = 0;
int c, h, l, ind;
for (int i = 0; i < gb.length;) {
if (gb[i] >= 0) {
fillBuffer(gb[i++]);
} else {
h = 256 + gb[i++];
l = 256 + gb[i++];
h = h - 0xA0 - 1;
l = l - 0xA0 - 1;
if (h < 9) {
ind = (h * 94 + l) << 1;
c = (byte2Int(map[ind]) << 8 | byte2Int(map[ind + 1]));
fillBuffer(c);
} else if (h >= 9 && h <= 14) {
fillBuffer(0);
} else if (h > 14) {
h -= 6;
ind = (h * 94 + l) << 1;
c = (byte2Int(map[ind]) << 8 | byte2Int(map[ind + 1]));
fillBuffer(c);
} else {
fillBuffer(0);
}
}
}
// ind = index - 2;
// h = (byte) ((ind >> 8) & 0x7F);
// l = (byte) (ind & 0xFF);
// buffer[0] = h;
// buffer[1] = l;
return new String(buffer, 0, index, "UTF-8");
}
private void fillBuffer(int value) {
if (value <= 0x0000007F) {
buffer[index++] = (byte) value;
} else if (value >= 0x00000080 && value <= 0x000007FF) {
byte b1 = (byte) (0x60 | (value >> 6));
byte b2 = (byte) (0x80 | (value & 0x3F));
buffer[index++] = b1;
buffer[index++] = b2;
} else if (value >= 0x00000800 && value <= 0x0000FFFF) {
byte b1 = (byte) (0xE0 | (value >> 12));
byte b2 = (byte) (0x80 | ((value >> 6) & 0x3F));
byte b3 = (byte) (0x80 | (value & 0x3F));
buffer[index++] = b1;
buffer[index++] = b2;
buffer[index++] = b3;
} else if (value >= 0x00010000 && value <= 0x001FFFFF) {
byte b1 = (byte) (0x1E | (value >> 18));
byte b2 = (byte) (0x80 | ((value >> 12) & 0x3F));
byte b3 = (byte) (0x80 | ((value >> 6) & 0x3F));
byte b4 = (byte) (0x80 | (value & 0x3F));
buffer[index++] = b1;
buffer[index++] = b2;
buffer[index++] = b3;
buffer[index++] = b4;
} else if (value >= 0x00200000 && value <= 0x03FFFFFF) {
byte b1 = (byte) (0x3E | (value >> 24));
byte b2 = (byte) (0x80 | ((value >> 18) & 0x3F));
byte b3 = (byte) (0x80 | ((value >> 12) & 0x3F));
byte b4 = (byte) (0x80 | ((value >> 6) & 0x3F));
byte b5 = (byte) (0x80 | (value & 0x3F));
buffer[index++] = b1;
buffer[index++] = b2;
buffer[index++] = b3;
buffer[index++] = b4;
buffer[index++] = b5;
} else if (value >= 0x04000000 && value <= 0x7FFFFFFF) {
byte b1 = (byte) (0x7E | (value >> 30));
byte b2 = (byte) (0x80 | ((value >> 24) & 0x3F));
byte b3 = (byte) (0x80 | ((value >> 18) & 0x3F));
byte b4 = (byte) (0x80 | ((value >> 12) & 0x3F));
byte b5 = (byte) (0x80 | ((value >> 6) & 0x3F));
byte b6 = (byte) (0x80 | (value & 0x3F));
buffer[index++] = b1;
buffer[index++] = b2;
buffer[index++] = b3;
buffer[index++] = b4;
buffer[index++] = b5;
buffer[index++] = b6;
}
}
private int byte2Int(byte b) {
if (b < 0) {
return 256 + b;
} else {
return b;
}
}
}
public class HGB2312 {
private byte[] map = new byte[15228];
private byte[] buffer;
private int index;
public HGB2312() throws Exception {
InputStream is = getClass().getResourceAsStream("/gb2u.dat");
is.read(map);
is.close();
}
public String gb2utf8(byte[] gb) throws Exception {
buffer = new byte[gb.length + gb.length / 2 + 3];
index = 0;
int c, h, l, ind;
for (int i = 0; i < gb.length;) {
if (gb[i] >= 0) {
fillBuffer(gb[i++]);
} else {
h = 256 + gb[i++];
l = 256 + gb[i++];
h = h - 0xA0 - 1;
l = l - 0xA0 - 1;
if (h < 9) {
ind = (h * 94 + l) << 1;
c = (byte2Int(map[ind]) << 8 | byte2Int(map[ind + 1]));
fillBuffer(c);
} else if (h >= 9 && h <= 14) {
fillBuffer(0);
} else if (h > 14) {
h -= 6;
ind = (h * 94 + l) << 1;
c = (byte2Int(map[ind]) << 8 | byte2Int(map[ind + 1]));
fillBuffer(c);
} else {
fillBuffer(0);
}
}
}
// ind = index - 2;
// h = (byte) ((ind >> 8) & 0x7F);
// l = (byte) (ind & 0xFF);
// buffer[0] = h;
// buffer[1] = l;
return new String(buffer, 0, index, "UTF-8");
}
private void fillBuffer(int value) {
if (value <= 0x0000007F) {
buffer[index++] = (byte) value;
} else if (value >= 0x00000080 && value <= 0x000007FF) {
byte b1 = (byte) (0x60 | (value >> 6));
byte b2 = (byte) (0x80 | (value & 0x3F));
buffer[index++] = b1;
buffer[index++] = b2;
} else if (value >= 0x00000800 && value <= 0x0000FFFF) {
byte b1 = (byte) (0xE0 | (value >> 12));
byte b2 = (byte) (0x80 | ((value >> 6) & 0x3F));
byte b3 = (byte) (0x80 | (value & 0x3F));
buffer[index++] = b1;
buffer[index++] = b2;
buffer[index++] = b3;
} else if (value >= 0x00010000 && value <= 0x001FFFFF) {
byte b1 = (byte) (0x1E | (value >> 18));
byte b2 = (byte) (0x80 | ((value >> 12) & 0x3F));
byte b3 = (byte) (0x80 | ((value >> 6) & 0x3F));
byte b4 = (byte) (0x80 | (value & 0x3F));
buffer[index++] = b1;
buffer[index++] = b2;
buffer[index++] = b3;
buffer[index++] = b4;
} else if (value >= 0x00200000 && value <= 0x03FFFFFF) {
byte b1 = (byte) (0x3E | (value >> 24));
byte b2 = (byte) (0x80 | ((value >> 18) & 0x3F));
byte b3 = (byte) (0x80 | ((value >> 12) & 0x3F));
byte b4 = (byte) (0x80 | ((value >> 6) & 0x3F));
byte b5 = (byte) (0x80 | (value & 0x3F));
buffer[index++] = b1;
buffer[index++] = b2;
buffer[index++] = b3;
buffer[index++] = b4;
buffer[index++] = b5;
} else if (value >= 0x04000000 && value <= 0x7FFFFFFF) {
byte b1 = (byte) (0x7E | (value >> 30));
byte b2 = (byte) (0x80 | ((value >> 24) & 0x3F));
byte b3 = (byte) (0x80 | ((value >> 18) & 0x3F));
byte b4 = (byte) (0x80 | ((value >> 12) & 0x3F));
byte b5 = (byte) (0x80 | ((value >> 6) & 0x3F));
byte b6 = (byte) (0x80 | (value & 0x3F));
buffer[index++] = b1;
buffer[index++] = b2;
buffer[index++] = b3;
buffer[index++] = b4;
buffer[index++] = b5;
buffer[index++] = b6;
}
}
private int byte2Int(byte b) {
if (b < 0) {
return 256 + b;
} else {
return b;
}
}
}
posted on 2008-08-15 14:47 LukeW 閱讀(633) 評(píng)論(0) 編輯 收藏 所屬分類: Tips, Tricks, Hints & Code