Java获取网卡接口名称的乱码问题

大概文字编码处理得多了,连同事遇到这方面问题,都跑过来问余了。
今晚同事遇到获取网卡接口名称乱码,无论怎么转都无法解决。
果然最好的方法还是查看字符串的二进制内容,乱猜是无用的。

平台是日文正版xp
NetworkInterface的getDisplayName()方法返回值是String,那确定就是一个Unicode字符串了
直接打印这个名称,最后一个”-“之后的字符串都不正常

使用String的getBytes(“UTF-16”)方法取出字串的二进制内容,全部打印出来,前几个以及最后几个的值如下

-2
-1
0
73  // -> I
0
110  // -> n
0
116  // -> t
0
101  // -> e
0
108  // -> l
...
...
...
0
-125
0
80
0
-125
0
87

首两个字符是-2,-1,也即0xFE,0xFF,大尾的BOM(Java你到底有多变态),每个字符都是高位在前
ASCII部分的字符高位为0,毫无疑问开头的几个字符就是Intel

来看最后几个字符
去掉0之后,序列是-125 80 -125 87,也即0x83 0x50 0x83 0x57,酷似多字节编码
打开WinHex(D版UltraEdit是不能装的),新建一个四字节文件,多字节编码在文本中都是先高位后低位,
于是按顺序写入16进制值,保存为txt文件
用记事本打开txt,结果是”ケジ”(日文版xp)
还可以用Ansi2Unicode打开,选择其他编码查看转换结果,Shift-JIS是最正常的了

于是终于可以下结论,这个字符串的原始编码就是Shift-JIS,但被分开成一个个byte,高位填充0,暴力转换为Unicode字符串。
这样的字符串非常的不正常,难怪怎么转都不对了

还原方法:去掉头部的BOM,去掉所有的0,得到二进制数组,在new一个String的同时,指定这个二进制数组的编码是Shift-JIS

import java.io.UnsupportedEncodingException;
import java.net.NetworkInterface;
import java.net.SocketException;
import java.util.Enumeration;

public class hello {

	public static void main(String[] args) {
		System.out.println("日本語");
		try {
			Enumeration interfaces = NetworkInterface.getNetworkInterfaces();
			while (interfaces.hasMoreElements()) {
				NetworkInterface ni = (NetworkInterface)interfaces.nextElement();
				byte[] b = ni.getDisplayName().getBytes("UTF-16");
				byte[] dst = new byte[b.length];
				for (int i=0; i<dst.length; i++) {
					dst[i] = 0;
				}
				int k=0;
				for (int i=0; i<b.length; i++) {
					if ((b[i]!=0) && (b[i]!=-1) && (b[i]!=-2)) {
						dst[k] = b[i];
						k++;
					}
				}
				String name = new String(dst, "Shift_JIS").trim();
				System.out.println(b.length);
				System.out.println(ni.getDisplayName());
				System.out.println(name);
			}
		} catch (SocketException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (UnsupportedEncodingException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
}

猜测是JDK调用了win32 api,却没有处理返回来的字符串编码
同事说Win7平台上没有问题,不需要转换,可能是因为win7系统的api返回的是Unicode字符串
这个修正方法和平台相关,很不通用

2011年11月17日 | 归档于 程序
标签: , ,
本文目前尚无任何评论.

发表评论

XHTML: 您可以使用这些标签: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>
:wink: :-| :-x :twisted: :) 8-O :( :roll: :-P :oops: :-o :mrgreen: :lol: :idea: :-D :evil: :cry: 8) :arrow: :-? :?: :!: