Java字符集研究

本文粗略了解下常用的编码方式。
众所周知,Java的char型占用两个字节,采用了Unicode编码方式的UTF-16实现。

iso8859-1

属于单字节编码,最多能表示的字符范围是0-255,应用于英文系列。比如,字母’a’的编码为0x61=97。

很明显,iso8859-1编码表示的字符范围很窄,无法表示中文字符。但是,由于是单字节编码,和计算机最基础的表示单位一致,所以很多时候,仍旧使用iso8859-1编码来表示。而且在很多协议上,默认使用该编码。比如,虽然”中文”两个字不存在iso8859-1编码,以gb2312编码为例,应该是”d6d0 cec4”两个字符,使用iso8859-1编码的时候则将它拆开为4个字节来表示:”d6 d0 ce c4”(事实上,在进行存储的时候,也是以字节为单位处理的)。而如果是UTF编码,则是6个字节”e4 b8 ad e6 96 87”。很明显,这种表示方法还需要以另一种编码为基础。

GB2312/GBK

这就是汉字的国标码,是双字节编码,而英文字母兼容iso8859-1编码。其中GBK编码能够用来同时表示繁体字和简体字,而GB2312只能表示简体字,GBK是兼容GB2312编码的。

unicode

是定长双字节的编码,想要表示世界上所有的语言文字,独成一个体系,不兼容其他编码。在我理解,它像一个标准,而常见的UTF规范包括UTF-8、UTF-16、UTF-32是对它的一种实现。
对于UTF-8,英文字母都是用一个字节表示,而汉字使用三个字节,所以在HTML文件传输中,一般英文字母比较多,UTF-8是比较节省的。

一个例子

package com.leo.character;

/**
 * 字符集的初探
 * Created by Leo on 2017/4/9.
 */
public class Main {
    public static void main(String[] args) throws Exception {
        //表明一个char占用两个字节
        char aChar = '中';
        System.out.println(Integer.toHexString(aChar));//输出:4e2d
        System.out.println("--------------------------------------");

        String a = "中";
        System.out.println(bytesToHexString(a.getBytes()));//输出:e4b8 ad     String.getBytes()默认采用本OS支持的编码方式
        System.out.println(bytesToHexString(a.getBytes("unicode")));//输出:feff 4e2d      为什么前面有feff不理解
        System.out.println(bytesToHexString(a.getBytes("utf-16")));//输出:feff 4e2d       可以看出java默认采用unicode的utf-16实现
        System.out.println(bytesToHexString(a.getBytes("utf-8")));//输出:e4b8 ad
        System.out.println(bytesToHexString(a.getBytes("GBK")));//输出:d6d0
        System.out.println(bytesToHexString(a.getBytes("iso8859-1")));//输出:3f   ?表示没有对应的编码

        String aa = "中文";
        System.out.println(bytesToHexString(aa.getBytes()));//输出:e4b8 ad
        System.out.println(bytesToHexString(aa.getBytes("unicode")));//输出:feff 4e2d 6587
        System.out.println(bytesToHexString(aa.getBytes("utf-16")));//输出:feff 4e2d 6587
        System.out.println(bytesToHexString(aa.getBytes("utf-8")));//输出:e4b8 ade6 9687
        System.out.println(bytesToHexString(aa.getBytes("GBK")));//输出:d6d0 cec4
        System.out.println(bytesToHexString(aa.getBytes("iso8859-1")));//输出:3f3f
    }

    /* *
     *  输出byte数组的十六进制表示
     *Convert byte[] to hex string.这里我们可以将byte转换成int,然后利用Integer.toHexString(int)
     *来转换成16进制字符串。
     * @param src byte[] data
     * @return hex string
     */
    public static String bytesToHexString(byte[] src){
        StringBuilder stringBuilder = new StringBuilder("");
        if (src == null || src.length <= 0) {
            return null;
        }
        for (int i = 0; i < src.length; i++) {
            int v = src[i] & 0xFF;
            String hv = Integer.toHexString(v);
            if (hv.length() < 2) {
                stringBuilder.append(0);
            }
            if ((i % 2) == 0 && i > 0) stringBuilder.append(" ");//每两个字节打一个空格
            stringBuilder.append(hv);
        }
        return stringBuilder.toString();
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值