`

ISO8859-1字符集与其他字符集兼容性测试

 
阅读更多

ISO8859-1字符集中所有字符只占一个字节,8位,一个字节的编码空间为0x00-0xFF共256个字符。

 

ISO8859-1字符集中的部分(GBK GB2312 )或全部(UTF-8 UTF-16)字符在其他字符集中会存在,而且编码值还相同。

 

当把一个字符集中某个字符转换成另外一种字符集中的字符时,在转换过程中会有很大一部分字符在另一种字符集中是没有的(比如GBK繁体字符到GB2312),这时会使用另一种字符集中的问号代替这个未知字符,且编为63。但一般从多字节编码字符集(GBK GB2312 UTF-8 UTF-16)转换成单字节字符ISO8859-1时,是可以映射的,不会出现找不到可映射字符,因为每个字节的内容在ISO8859-1中都是找得到的,这就是为什么把一个 GBK、GB2312、UTF-8等编码的字符串以IS08859-1编码后,编码信息不会丢失的原因,最后还是可以还原成原来样子。

 

在Java里从一种字符转换成另一种字符集中的字符时,转换过程是要借助中间编码的,这个中间码就是Java语言本身所使用的编码——Unicode。现以ISO8859-1字符集中的¤字符转为GBK中的该字符为例:¤的ISO8859-1编码为A4,转换到Unicode字符集中后还是为A4(Unicode前256字个符与ISO8859-1是完全兼容的),然后由中间Unicode码映射到GBK字符集中相应字符,如果这个Unicode字符在GBK中存在,则使用对应的GBK编码,否则使用问号编码63代替,当然这一中间转换过程是由Java来帮我们实现的,最后我们的感觉就是由ISO8859-1直接转到了GBK编码。注,两种不同的编码中的相同的字符的编码不一定相同,这就是所谓的编码不兼容问题,比如说ISO8859-1字符¤的编码为A4,而映射到UTF-8后所对应的编码却为C2A4了。

 

从输出的附件可以看出(注,最好用记事本打开),GB2312、GBK、UTF-8字符集能兼容(兼容是指同一字符在两种不同字符集中都存在且编码还要相同)ISO8859-1的0x00-0x7F共128个字符。

 

ISO8859-1字符映射到GB2312、GBK字符集中后,能映射的字符这两种字符集基本上一样,只是在GBK字符集比GB2312多映射一个字符(B7·)。

 

ISO8859-1中编码大于0x7F的字符可全部映射到UTF-8字符,只是编码占用了两字节,但0x7F之后的字符只有一部分可以映射到GB2312、GBK字符集中。

 

Unicode、UTF-16编码完全兼容ISO8859-1字符集,即ISO8859-1中的字符在Unicode、UTF-16中存在,且编码完全相同。

 

编码大于0x7F的ISO8859-1字符,能映射到GB2312、GBK、UTF-8的都占两个字节,UTF-16就不用说了,肯定是两字节,只不过编码未变。

 

下面程序就是用来把ISO8859-1字符集映射到其他字符集的代码,它会把映射完后的字符分别输出到不同文件中,且无法映射(只ISO8859-1中某字符无法在其他字符集中找到)的字符不会输出到文件中。

 

import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.io.UnsupportedEncodingException;

/**
 * ISO8859-1与其他字符兼容性测试
 * @author jzj
 */
public class ISOCharSet2OtherCharSet {
	public static void main(String[] args) throws UnsupportedEncodingException {
		try {
			String charSet = "GBK";
			toOtherCharSet(charSet);
			charSet = "UTF-8";

			toOtherCharSet(charSet);
			charSet = "GB2312";
			toOtherCharSet(charSet);

			charSet = "UTF-16";
			toOtherCharSet(charSet);
		} catch (UnsupportedEncodingException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

	private static void toOtherCharSet(String charSet)
			throws UnsupportedEncodingException, FileNotFoundException, IOException {
		OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream("e:/tmp/"
				+ charSet + ".txt"), charSet);
		osw.write("可映射字符 ISO8859-1 -> " + charSet + "\r\n");
		osw.write("\r\nISO8859-1=XX" + " " + charSet + "=XX\r\n");

		StringBuffer sb = new StringBuffer();
		//遍历256个ISO8859-1字符
		for (int i = 0; i <= 255; i++) {
			//ISO8859-1字符真实编码
			byte[] b = new byte[] { (byte) i };

			byte[] encodeArr = new String(b, "ISO8859-1").getBytes(charSet);
			short codeShort = encodeArr[0];

			/*
			 * 只有UTF-16才是固定4字节(前两字节为FE FF,后两个字节者是真真内容),其他编码可编码后为一个
			 * 字节,也可能为两个字节,且真实编码最多为两个字节。所以单字节ISO字符在其他字符集中可能为双字
			 * 节,如果为双字节时,取后两个字节(针对UTF-16,其他字符集最多为双字节)。
			 */
			if (encodeArr.length > 1) {
				codeShort = (short) ((encodeArr[encodeArr.length - 2] << 8) | (encodeArr[encodeArr.length - 1] & 0x00FF));
			}
			String gbkEncodeHex = short2Hex(codeShort);
			String isoEncodeHex = byte2Hex((byte) i);

			//如果ISO字符不能转换到指定的字符集中的字符时,会以问号替换,这里不输出不能映射的字符
			if (codeShort != 63 || (i == 63)) {
				osw.write(isoEncodeHex + "=" + new String(b, "ISO8859-1") + " ");
				osw.write(gbkEncodeHex + "=" + new String(encodeArr, charSet) + "\r\n");
			}
			//记录不兼容字符,即ISO8859-1中的字符在其他字符集中不存在,排除问题,因为问题肯定是兼容的
			if (codeShort == 63 && i != 63) {
				sb.append(isoEncodeHex);
				sb.append("=");
				sb.append(new String(b, "ISO8859-1"));
				sb.append("\r\n");
			}
		}
		if (sb.length() > 0) {
			osw.write("\r\n不兼容字符:\r\n" + sb);
		}
		osw.flush();
		osw.close();
	}

	/**
	 * 短整型转十六进制
	 * @param coding
	 * @return
	 */
	private static String short2Hex(short coding) {
		return Integer.toHexString(coding & 0x00FFFF | 0xFF0000).toUpperCase().substring(
				2, 6);
	}

	/**
	 * 字节型转十六进制
	 * @param coding
	 * @return
	 */
	private static String byte2Hex(byte coding) {
		return Integer.toHexString(coding & 0x00FF | 0xFF00).toUpperCase()
				.substring(2, 4);
	}
}

 

分享到:
评论

相关推荐

    Ftp_File.rar_ftp iso-8859-1_ftp_file labview_site:en.pudn.com

    在文档转换中,将日文文档转换为ISO-8859-1编码可能是因为某些系统或软件只支持这种编码,或者是为了兼容性考虑。需要注意的是,非ASCII字符在转换过程中可能会丢失或显示为乱码,因此这种转换需谨慎操作。 LabVIEW...

    Oracle 字符集详解

    使用`expdp`和`impdp`工具时,应确保源数据库和目标数据库的字符集兼容。如果不一致,可以使用`CHARSET`参数指定目标字符集: ```bash expdp user/pwd directory=dir_name dumpfile=data.dmp logfile=expdp.log ...

    ISO7816-1~15.rar

    这个压缩包“ISO7816-1~15.rar”包含了从1到15的全部标准文档,为智能卡的开发提供了详尽的技术指导。 1. ISO7816-1:物理特性 这部分规定了智能卡的尺寸、形状、材料、机械强度等物理属性,以及卡片的接触区域和...

    informix字符集转换

    这段代码首先设置了默认的英语(美国)字符集为`.819`,然后将其更改为ISO 8859-1标准的字符集。ISO 8859-1也被称为“Latin-1”,是西欧语言的编码标准。 - **简体中文到GBK (GB18030-2000)**: ```sh export DB_...

    sybase字符集的更改

    Sybase ASE 支持多种字符集,如 ISO-8859-1、Windows-1252、CP936 等。 #### 二、更改 Sybase ASE 字符集的原因 更改 Sybase ASE 的字符集通常是因为以下几种情况: 1. **国际化需求**:随着业务扩展到不同地区,...

    oracle字符集资料

    Oracle支持多种字符集,包括ASCII、ISO-8859-1、AL32UTF8(即UTF-8)等。其中,ASCII是最基础的7位字符集,包含128个字符;ISO-8859-1是扩展的8位字符集,支持更多的西欧语言;而AL32UTF8是广泛使用的Unicode字符集...

    Charset_SingleByte_ISO_8859_8.rar_single

    总之,这个压缩包提供了一个研究和学习ISO 8859-8字符编码的实例,通过分析源代码和运行Shell脚本,我们可以深入了解如何在Linux系统中处理这种单字节编码,并对比它与其他编码(如UTF-8)的差异和兼容性问题。...

    ORACLE 字符集简介

    选择合适的字符集不仅能够确保数据的正确存储和检索,还能有效避免未来可能出现的迁移和兼容性问题。通过本文的介绍,希望能够帮助读者更好地理解和掌握Oracle字符集的相关知识,从而在实际应用中更加得心应手。

    Oracle切换客户端字符集

    2. 兼容性检查:在切换字符集之前,确保新的字符集与数据库服务器兼容,否则可能导致通信问题。 3. 测试验证:切换字符集后,进行测试以确认所有操作(如查询、插入、更新等)正常,没有出现乱码或错误。 总结,...

    mysql数据库互相转换及同步工具-MySQL_MySQL字符集互转

    1. **字符集的概念**:字符集是数据库用来表示文本字符的编码方式,例如ASCII、ISO-8859-1、UTF-8等。不同的字符集支持的字符范围和占用的存储空间不同。 2. **MySQL字符集转换**:在MySQL中,可以使用ALTER TABLE...

    中文转码工具.rar

    - **字符范围问题**:ISO-8859-1无法直接表示中文字符,因此在转换过程中,任何超出ISO-8859-1字符集范围的字符(如中文字符)都将被转换为问号或其他替换字符。这可能导致信息丢失,需要谨慎操作。 - **转换方法**...

    iso+iec7811-1

    ### ISO/IEC 7811-1:2002(E) 国际标准解析 #### 标准概述 ISO/IEC 7811-1:2002(E) 是一个关于识别卡片记录技术的国际标准,特别关注了卡片的凸印(Embossing)技术。该标准定义了一系列规范和技术要求,旨在确保...

    常用6500字符集,用于制作图集

    总的来说,"常用6500字符集"是Unicode编码中的一个重要部分,它广泛应用于跨语言的文本处理和图形设计,确保了不同语言之间的兼容性和互操作性。了解和掌握这种字符集对于进行国际化和本地化的工作至关重要。

    HTML1114 (HTTP 标头)的代码页 gb2312 覆盖(META 标记)的冲突的代码页 utf-8

    2. **DOMINO配置修改**: 如果使用的是IBM Domino服务器,需要确保服务器文档中的Internet协议(Domino Web引擎字符集)设置为utf-8。具体操作是,在相关设置中选择“在HTML表单中使用UTF-8”,并重启服务器以使更改...

    前端开源库-iso-random-stream

    2. **跨平台兼容性**:库的设计考虑到了Node.js和浏览器环境的差异,因此可以在这两种环境中无缝工作,无需额外的适配器或polyfill。 3. **API接口**:iso-random-stream 提供了一个简单易用的API,允许开发者轻松...

    java解决解决get中文乱码问题

    这个问题主要是因为浏览器发送GET请求时,参数默认使用ISO-8859-1编码格式,而服务器端通常采用的是其他编码(如GBK、UTF-8等)。当客户端与服务器端使用的字符集不一致时,就会导致乱码问题的发生。本文将详细介绍...

    Unicode介绍,i18n测试需要的了解的知识,很全面很详细。

    - **单字节字符集(SBCS)**:如ASCII和ISO-8859-1,适用于有限数量的字符,如拉丁字母。 - **双字节字符集(DBCS)**:如GBK、Big5,适用于东亚语言,两个字节表示一个字符。 - **多字节字符集(MBDC)**:如UTF-8,...

Global site tag (gtag.js) - Google Analytics