守望者--AIR技术交流

 找回密码
 立即注册

QQ登录

只需一步,快速开始

扫一扫,访问微社区

搜索
热搜: ANE FlasCC 炼金术
查看: 1753|回复: 0

[算法/性能优化] AS3从未知编码的二进制流中自适应编码读取文本

[复制链接]
  • TA的每日心情
    擦汗
    2018-4-10 15:18
  • 签到天数: 447 天

    [LV.9]以坛为家II

    1742

    主题

    2094

    帖子

    13万

    积分

    超级版主

    Rank: 18Rank: 18Rank: 18Rank: 18Rank: 18

    威望
    562
    贡献
    29
    金币
    52691
    钢镚
    1422

    开源英雄守望者

    发表于 2015-1-8 18:05:37 | 显示全部楼层 |阅读模式

    给你一个文件或者二进制,不知道编码是gb2312还是utf8的情况下怎么正确读取出文本呢?

    以下代码是as3的,其他编程语言只要稍微改动一下即可。

    上代码,请直接用!

    (感谢C++ BLOG提供的判断utf8的方法:http://hi.baidu.com/xingyan126/item/4abec1c1c2143755bcef6956

    1. /**
    2. * 从未知编码的二进制流中读取文本
    3. * @param   ba
    4. * @param   len 读取长度,默认为-1,则读取至文件尾
    5. * @return
    6. */
    7. public static function readString(ba:ByteArray,len:int = -1):String
    8. {
    9.     if ((len != -1 && len > ba.bytesAvailable) || (len == -1)) len = ba.bytesAvailable;
    10.     var encode:String = 'gb2312';
    11.     //先判断头三个字节是不是utf bom
    12.     if (ba.bytesAvailable >= 3)
    13.     {
    14.         //0xEF 0xBB 0xBF
    15.         var chkarr:Array = [];
    16.         var a:int = 0xffffffEF;
    17.         var b:int = 0xffffffBB;
    18.         var c:int = 0xffffffBF;
    19.         chkarr.push(ba.readByte());
    20.         chkarr.push(ba.readByte());
    21.         chkarr.push(ba.readByte());
    22.         if ((chkarr[0] == a && chkarr[1] == b && chkarr[2] == c))
    23.         {
    24.             //utf-8 bom
    25.             encode = 'utf-8';
    26.             return ba.readMultiByte(len - 3, encode);
    27.         }
    28.         else
    29.         {
    30.             ba.position -= 3;
    31.         }
    32.     }
    33.      
    34.     //逐个字节判断是否有UTF8的编码
    35.     if (isUTF8(ba, len))
    36.     {
    37.         encode = 'utf-8';
    38.     }
    39.      
    40.     return ba.readMultiByte(len - 3, encode);
    41. }

    42. /**
    43. * 判断文本是否是UTF8编码
    44. * @param   ba
    45. * @param   len 读取长度,默认为-1,则读取至文件尾
    46. * @return
    47. */
    48. public static function isUTF8(ba:ByteArray,len:int = -1):Boolean
    49. {
    50.     if ((len != -1 && len > ba.bytesAvailable) || (len == -1)) len = ba.bytesAvailable;
    51.     var score:int = 0;
    52.     var i:int;
    53.     var goodbytes:int = 0, asciibytes:int = 0;
    54.     // Maybe also use UTF8 Byte Order Mark: EF BB BF
    55.     // Check to see if characters fit into acceptable ranges
    56.     var oldpos:int = ba.position;
    57.     var byte:int, byte1:int, byte2:int;
    58.     var curlen:int = len;
    59.     while(curlen>0)
    60.     {
    61.         ba.position = oldpos + (len - curlen);
    62.         byte = ba.readByte();
    63.         curlen -= 1;
    64.         if (curlen >= 1) byte1 = ba.readByte();
    65.         if (curlen >= 2) byte2 = ba.readByte();
    66.          
    67.         //0x7f = 127 = 01111111
    68.         if ((byte & 0x7F) == byte)  
    69.         {  
    70.              // 最高位是0的ASCII字符
    71.              asciibytes++;
    72.              // Ignore ASCII, can throw off count
    73.         }  
    74.         else if (-64 <= byte && byte <= -33
    75.              //-0x40~-0x21
    76.              && // Two bytes
    77.              curlen >= 1 && -128 <= byte1
    78.              &&  
    79.              byte1<= -65)  
    80.         {
    81.              goodbytes += 2;
    82.              curlen -= 1;
    83.         }  
    84.         else if (-32 <= byte
    85.             && byte <= -17
    86.             && // Three bytes
    87.             curlen >= 2 && -128 <= byte1
    88.             && byte1 <= -65 && -128 <= byte2
    89.             && byte2 <= -65)  
    90.         {
    91.             goodbytes += 3;
    92.             curlen -= 2;
    93.         }
    94.     }
    95.      
    96.     ba.position = oldpos;
    97.      
    98.     if (asciibytes == len)  
    99.     {
    100.         return false;
    101.     }
    102.     score = 100 * goodbytes / (len - asciibytes);
    103.     // If not above 98, reduce to zero to prevent coincidental matches
    104.     // Allows for some (few) bad formed sequences
    105.     if (score > 98) {
    106.         return true;
    107.     } else if (score > 95 && goodbytes > 30) {
    108.         return true;
    109.     } else {
    110.         return false;
    111.     }
    112. }
    复制代码
    作者:YoYo,原文地址:http://yoyo.play175.com/p/207.html


    守望者AIR技术交流社区(www.airmyth.com)
    回复

    使用道具 举报

    您需要登录后才可以回帖 登录 | 立即注册

    本版积分规则

    
    关闭

    站长推荐上一条 /4 下一条

    QQ|手机版|Archiver|网站地图|小黑屋|守望者 ( 京ICP备14061876号

    GMT+8, 2024-4-18 22:53 , Processed in 0.084362 second(s), 35 queries .

    守望者AIR

    守望者AIR技术交流社区

    本站成立于 2014年12月31日

    快速回复 返回顶部 返回列表