出现乱码原因
乱码其实是不相应字符集而造成部分或所有字符无法被阅读的一系列字符,就是我们看不懂,外国人可能看得懂。
这里dicom tag(0008,0005)也就是dicom的特殊字符集,图片显示的ISO_IR 100是dicom的默认字符集。
dicom标准里支持以下字符集Supported Specific Character Set Defined Terms:如下图所示:
从图中可以看出ISO_IR 100对应的就是我们平时经常遇到的ISO-8859-1(Latin alphabet No. 1是ISO-8859-1的别名)编码。 而ISO-8859-1是单字节编码,自身不能显示中文,若要显示中文,必须和其他能显示中文的编码配合,如“GBK”,“UTF-8"。
dicom协议本身也有这样一段介绍Extension or Replacement of the Default Character Repertoire:
For Data Elements with Value Representations of SH (Short String), LO (Long String), UC (Unlimited Characters), ST (Short Text), LT (Long Text), UT (Unlimited Text) or PN (Person Name) the default character repertoire may be extended or replaced (these Value Representations are described in more detail in Section 6.2). If such an extension or replacement is used, the relevant "Specific Character Set" shall be defined as an attribute of the SOP Common Module (0008,0005) (see PS3.3) and shall be stated in the Conformance Statement. PS3.2 gives conformance guidelines.
大意是VR使用SH (Short String), LO (Long String), UC (Unlimited Characters), ST (Short Text), LT (Long Text), UT (Unlimited Text) or PN (Person Name)时会使用默认字符集来解码。
知道了出现乱码的原因,那就好解决了。
java解决乱码
当然解决的方式很简单:
String string = "΢ÈíÖйú";
String s = new String(string.getBytes("ISO-8859-1"), "gbk");
System.out.println(s);
运行上面代码获取到的结果:微软中国
当然使用GB18030编码也是可以解决的。
问题虽然解决了,好奇的想通过计算机去还原一下乱码。
String string = "΢ÈíÖйú";
byte[] bs = string.getBytes("ISO-8859-1");
for (int i = 0; i < bs.length; i++) {
System.out.print((bs[i]) + ",");
}
我们先获取乱码的字节数组,得到以下结果: -69,-58,-20,-49,-70,-22,94,-60,-48,94,94,94,
这里的负数是因为计算机是利用二进制的补码进行存储的。
我们将其&0xff以保证二进制补码一致性,如下:
String string = "΢ÈíÖйú";
byte[] bs = string.getBytes("ISO-8859-1");
for (int i = 0; i < bs.length; i++) {
System.out.print((bs[i] & 0xff) + ",");
}
得到的结果是:206,162,200,237,214,208,185,250, 去对比一下ISO-8859-1表ISO 8859-1 符号实体,将其结果与实体编号对比得到的结果正好是:΢ÈíÖйú