黑马程序员技术交流社区

标题: 字符编码问题 [打印本页]

作者: 杨成    时间: 2013-8-27 02:03
标题: 字符编码问题
本帖最后由 杨成 于 2013-8-29 12:34 编辑

复习毕老师视频时候,看到了"联通"这个编码转换问题,有个疑惑。先看代码:
  1. /*
  2. 联通:
  3. */
  4. class EncodeDemo2
  5. {
  6.         public static void main(String[] args)throws Exception
  7.      {
  8.              String s="联通";
  9.              byte[] by=s.getBytes("GBK");
  10.              for(byte b:by)
  11.             {
  12.                   System.out.print(Integer.toBinaryString(b&255)+"\t");
  13.             }
  14.            System.out.println("\n"+new String(by,"UTF-8"));
  15.        }
  16. }
复制代码
运行结果:


但是查阅JDK_API文档的时候看到了这个:


按理来说   11000001        10101010        11001101        10101000 根据JDK中UTF-8解析的话,查表是11000001        10101010 对应一个字符,11001101        10101000 对应令一个字符,按理来说结果应该是两个字符(??)啊,怎么结果会出现三个字符(???),求大神们给个来龙去脉的分析,小弟感激不尽!

作者: 黄文伯    时间: 2013-8-27 08:41
亲,如问题已解决请将分类的“未解决”改为“已解决”。
以后的问题贴也要及时更改分类哦~
作者: binghaiwang    时间: 2013-8-27 14:06
本帖最后由 binghaiwang 于 2013-8-27 14:11 编辑

不好意思,刚误导了。因此我删除内容了。我先去看下这个问题。
作者: 杨成    时间: 2013-8-27 15:21
黄文伯 发表于 2013-8-27 08:41
亲,如问题已解决请将分类的“未解决”改为“已解决”。
以后的问题贴也要及时更改分类哦~ ...

好的,但目前还没有人帮我解决啊,版主{:soso_e154:}

作者: straw    时间: 2013-8-28 22:44
楼主真是太细心了!佩服啊!
关于你问的问题我重新对u8码表进行了编码规范的学习,也终于找到答案了:
楼主能问这个问题说明你已经知道的了u8的基本编码规范了,当码表得到
11000001        10101010        11001101        10101000  这堆二进制描述的字节数组时,
1,首先会进行判断是否符合u8的编码规范?符合那种规范?
   很显然第一个字节和第二个字节的标记来看符合了用两个字节来描述的u0000~u0080的字符集,到这里
  我们通常认为码表会立即用这两个字节去匹配一个字符(当没有找到是就用一个"?"来代替),其实并非如此
  ,码表还会对标记符后面的字符表示位进行验证,很显然11000001的有效位只有1个位,10101010有效位有6个为,那么11000001        10101010 总共真实的有效位是7个,说明这个字符用一个字节刚好可以描述!所以码表就会用11000001去单独描述这个字符而最终没有匹配到所以用一个"?"代替.
  1. public static void main(String[] ages)throws Exception{
  2.                 //定义一个字节数组
  3.         byte[] bt={-63,-86};
  4.         //输出该字节数组转换成的二进制
  5.         for(byte b:bt){
  6.                 System.out.println(Integer.toBinaryString(b&255));
  7.         }
  8.         //用该字节数组去匹配UTF-8码表
  9.         System.out.println(new String(bt,"utf-8"));
  10.         }
复制代码
输出:11000001  10101010  ??

如果我们将字节数组值-63改成-62:
  1. public static void main(String[] ages)throws Exception{
  2.                 //定义一个字节数组
  3.         byte[] bt={-62,-86};
  4.         //输出该字节数组转换成的二进制
  5.         for(byte b:bt){
  6.                 System.out.println(Integer.toBinaryString(b&255));
  7.         }
  8.         //用该字节数组去匹配UTF-8码表
  9.         System.out.println(new String(bt,"utf-8"));
  10.         }
复制代码
输出结果:11000010  10101010 ?

重结果来看说明我们分析是对的.

2,当匹配完一个字节后,再反复按照这个规则进行匹配直到匹配完数组中全部字节为止.
所以就会出现为什么?11000001        10101010        11001101        10101000解码时不是"??"而是"???".







作者: 杨成    时间: 2013-8-29 00:22
straw 发表于 2013-8-28 22:44
楼主真是太细心了!佩服啊!
关于你问的问题我重新对u8码表进行了编码规范的学习,也终于找到答案了:
楼主能问 ...

非常感谢兄弟你花时间来为我解答!
但是我还是对这块存有质疑,为什么前两个字节的有效位是7位,它就反过去读第一个字节呢?这不是多此一举?明明按UTF-8的解码方式,对应的这个解码的方式是,2个字节为一个字符,而因为有效位的问题去读第一个字节,然后再按正常的规则去解读,我觉得这很不可思议!

等我进去了,一定要当毕老的面问清楚,凭啥这块就一笔带过了?  明显的三个?怎么去解读的都没有说清楚!

PS:兄弟你准备进那个班呢?复习到哪了?

作者: straw    时间: 2013-8-29 01:17
云六啊!我现在都还没辞职呐!复习得马马虎虎,一天都没什么时间.

对于的疑问,我的理解是编码如果能用一个字节去描述的字符就会尽量只用一个字节,而不是多次一举去用两个字节,当然也可以描述出来,但是会浪费一半的空间.所以编码器在验证过程中就很有必要执行这个动作.

作者: 杨成    时间: 2013-8-29 01:26
straw 发表于 2013-8-29 01:17
云六啊!我现在都还没辞职呐!复习得马马虎虎,一天都没什么时间.

对于的疑问,我的理解是编码如果能用一个字 ...

大哥知道6期的面试最迟时间吗?
作者: straw    时间: 2013-8-29 21:31
杨成 发表于 2013-8-29 01:26
大哥知道6期的面试最迟时间吗?

按往届来看,应该是10月10号这样

作者: 杨成    时间: 2013-8-29 22:54
straw 发表于 2013-8-29 21:31
按往届来看,应该是10月10号这样

这么晚啊{:soso_e127:}!
唉,我现在都不知道技术博客怎么写了,看视频的讲解很细,如果总结到博客也那么细的话,那不就等于是把老师的课件和代码自己输了一遍吗?这样到时候提交技术博客的时候,老师会不会认为我在偷懒呢?如果只是简单的总结的话,有感觉里面的内容不够,将来复习的话,也不全面。

PS:我现在很纠结啊,不知道该怎么办{:soso_e150:}

作者: straw    时间: 2013-8-29 23:11
技术博客千万不要将视频中老师说的敲的代码一一的复制上去啊!其实技术博客是对某种技术的深入学习研究,我们不一定要达到专家那种级别,但是内容中要有自己的观点看法,或者一些自己揣摩出的新解决方案.或者是对某个问题的发现以及解决的办法等...
确实写一遍博客不容易啊,不过也还有时间啊,我应该比你还糟啊,每天只有3个小时不到的学习时间啊.看你问的问题就知道你是这行的好苗子啊!不抛弃不放弃...
作者: 杨成    时间: 2013-8-29 23:18
straw 发表于 2013-8-29 23:11
技术博客千万不要将视频中老师说的敲的代码一一的复制上去啊!其实技术博客是对某种技术的深入学习研究,我们 ...

唉,我今年才刚刚毕业。学校学的还不错,但是我那是个大专学校,学校对学生的要求就那样了。我也是去年8月份才意识到问题了,才边看毕老师的视频边做记录的,写了25天的。之后一直到现在不是学校的事,就是家里的事,一直没有时间看新知识。最近才有了时间,所以就报名了。我7月份毕业证领了后,出来找工作就有问题了,如果没有WEB方面一定的技术,真不好在西安找!真心希望能进去,就是这环节有点太多了,真心希望啥时候能优化下!

作者: straw    时间: 2013-8-30 23:11
杨成 发表于 2013-8-29 23:18
唉,我今年才刚刚毕业。学校学的还不错,但是我那是个大专学校,学校对学生的要求就那样了。我也是去年8 ...

不要灰心,我们经历的这些节点其实就是在培养我们的自学与沟通能力,你别看过程很繁琐,其实外面很多程序员只知道用不知道底层是怎么实现的,出了问题就一头雾水.更要命的是出现了新技术也不知道如何下手去学习!





欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/) 黑马程序员IT技术论坛 X3.2