utf8与unicode转换

来源:互联网 发布:类似初页的软件 编辑:程序博客网 时间:2024/05/17 03:34

     前端时间要自己实现utf8和unicode格式转换,打算封装一个类。也想过偷懒,直接网上找一个拿来用,但是后来发现问题多多。首先:接口不一样,其次:网上大部分方法还是不靠谱的,或者说:方法现在已经已经不适用了。

     关于二者转换的原理网上很多,这里就不赘述了。主要说一下我遇到的问题:

     我希望写成的接口是这个样子的:

      

    亦即:外边分配好存储转换结果的空间,而后在方法中对其进行赋值。

 

   问题1:如何做参数有效性检查。检查集中在结果存储空间是否足够大小上。由于utf8是变长的,在转换结束之前永远不知道其具体占用多大空间,所以不好先期判断。可能也有人说了:Unicode2Utf8时我直接开3倍+1大小的空间,Utf82Unicode直接开2k+2的空间不就足够了?在转换函数中直接判断结果存储空间达没达到这个大小不就OK了?的确,这样没错。但是作为一个完善的类,这样是不严谨的!比如:Unicode2Utf8时可能提供的结果串只需要2k空间就足够了,外边也开了2倍空间,但是我们函数中上来就判断其不到3倍+1然后给报错了,这显然不行!所以:用最大空间来判断不好!

    解决:1:网上也有人这么做,就是结果存储空间是在转换函数内部分配的,外部只是声明了一个指针而已。这样随着转换的进行,同时追加分配新空间! 这样的确解决了上边的问题,但是分配空间本身是相当消耗资源的,这函数的效率就低了!

             2:我用的方法:在转换前也做一次遍历,看每个字符转换后占用几个byte,进行累加。依据最后的值判断参数的有效性!这样虽然给人感觉多做了一遍,但是较为严谨!

 

 

  问题2:比如在Utf82Unicode时,我们需要看每个byte的前几位是否满足utf8的格式定义,这要用到:从一个字节中取出前/后若干位来。网上很多方法都是简单的直接做了个移位操作,比如:0xff<<5 。但是这样显然会遇到一个很基础的错误!

把问题抽象出来:0xff << 5 和 0xe0是一样的吗?嗯,有时候一样,有时候不一样!当直接使用<< 或>>进行位移操作时:你要明白它在cpu中是如何进行的。比如一个32位宽的cpu,当执行0xff << 5时:高位移除的5位并没有丢失掉!毕竟32位宽,所以移位完之后变为:0x1fe0 ,这也是为什么0xff << 5 和 0xe不一定相等的原因。二者相等不相等取决于cpu的位宽! 网上很多算法都没有注意到这点,我猜测那些算法都是8位宽时代实现的,后来放网上时也没去修改。但是这种不同只有在左移时才发生,右移时不会发生!这提示我们:在使用时尽可能少用移位操作符,本身考虑的东西太多而且代码阅读性也不好。

 

---------------------------------------------------------------------------------------------------------------------------------------------------

基础补充:

      1:一个unicode在内存中占用2个byte。而utf是一种存储格式,其是变长的,最长可达6byte。但是基本上3个byte已经包括目前所能用到的全部字符了。 所以:Unicode2Utf8时最坏情况为:每个Unicode转完后都占用3个byte,所以最大要开3倍空间,再加上有一个/0结束符,所以最大需要开3k+1的空间!  而Utf82Unicode时:最坏情况下每个Utf8都转为一个unicode,亦即原本的每个byte先变为2个byte,再加上最后两个byte的/0  所以最大需要开2k+2的空间!

---------------------------------------------------------------------------------------------------------------------------------------------------

   下边是我封装的类代码,有错误大家指正。

 

原创粉丝点击