zoukankan      html  css  js  c++  java
  • UTF8转换UTF16(Unicode) 汇编实现

      1 DWORD UTF8ToUnicode(LPVOID utf8Bytes,DWORD bytesLength,LPVOID *unicodeBytes)
      2 {
      3     DWORD charsCount=0;
      4     DWORD result;
      5     LPDWORD pResult=&result;
      6     LPVOID tmpBuffer=NULL;
      7     LPBYTE tmpData=(LPBYTE)utf8Bytes;
      8     if(IsUTF8Data(tmpData))
      9     {
     10         utf8Bytes=tmpData+3;
     11         bytesLength-=3;
     12     }
     13     *unicodeBytes=malloc(bytesLength*2);//分配最大可能需要的内存
     14     //EAX:需要计算的数据
     15     //EBX:操作状态
     16     //ECX:最大源地址
     17     //EDX:计算结果
     18     //ESI:源
     19     //EDI:目标
     20     __asm
     21     {
     22         //push eax;                //对使用到的寄存器进行保存
     23         //push ebx;                //对使用到的寄存器进行保存
     24         //push ecx;
     25         //push edx;
     26         //push esi;
     27         //push edi;
     28         pushad;
     29         MOV eax,0;                
     30         mov esi,utf8Bytes;            //设置源地址
     31         mov edi,DWORD PTR[unicodeBytes];            //设置目标地址
     32         mov edi,DWORD PTR[EDI];
     33         mov ecx,bytesLength;    
     34         add ecx,esi;            //计算源数据最高地址
     35         MOV EBX,pResult
     36             XOR EAX,EAX;
     37         XOR EDX,EDX;
     38 LoopStart:;
     39         mov EAX,DWORD PTR[ESI];//读取数据
     40 
     41         test al,0x80;
     42         jz L1;
     43         test al,0x40;
     44         JZ LoopEnd;            //错误数据
     45         TEST AL,0x20;
     46         JZ    L2;
     47         JNZ L3;
     48 
     49         NOT EBX;     //遇到无效字符(不支持四字节字符)
     50         JMP    LoopEnd;
     51 L3:;
     52         AND EAX,0x003F3F0F;
     53         ADD DL,AL;
     54         SHL EDX,6;
     55         SHR EAX,8;
     56         ADD DL,AL;
     57         SHL EDX,6;
     58         //SHR EAX,8;
     59         ADD DL,AH;
     60         ADD ESI,3;
     61         JMP END;
     62 L2:;
     63         AND EAX,0x00003F1F;
     64         ADD DL,AL;
     65         SHL EDX,6;
     66         //SHR EAX,8;
     67         ADD DL,AH;
     68         ADD ESI,2;
     69         JMP END;
     70 L1:;
     71         MOV DL,AL;
     72         ADD ESI,1;
     73         //SHL EDX,8;
     74 END:;
     75         MOV WORD PTR [EDI],DX;
     76         XOR EDX,EDX;
     77         ADD EDI,2;
     78 
     79         CMP ESI,ECX;
     80         JNGE LoopStart;//如果ESI小于ECX 继续循环
     81 
     82         MOV WORD PTR [EDI],0;
     83         MOV DWORD PTR[EBX],EDI;
     84 LoopEnd:;
     85         //错误的数据
     86         popad
     87             //pop edi;    //恢复使用到的寄存器
     88             //pop esi;
     89             //pop edx;
     90             //pop ecx;
     91             //pop ebx;
     92             //pop eax;
     93     }
     94     if(result!=-1)
     95     {
     96         charsCount=result-(DWORD)*unicodeBytes;
     97         tmpBuffer=malloc(charsCount+4);
     98         memset(tmpBuffer,0,charsCount+4);
     99         memcpy(tmpBuffer,*unicodeBytes,charsCount);
    100         free(*unicodeBytes);
    101         *unicodeBytes=tmpBuffer;
    102     }
    103     return charsCount;
    104 }

    UTF-8编码转换Utf-16

    以上代码不转换4字节Utf-8编码字符,因为4字节Utf-8编码字符无法在UTF-16保存,最大0X1FFFF而Utf-16最大0xFFFF;utf-32可以保存

    Utf-16编码和Unicode是一一对应的,Unicode程序中使用的也就是utf-16;

    所以很多时候需要进行转换,utf-8保存英文字符占用空间小于utf-16,但是对于中文大于utf-16占用的空间

    首先一次性取4个字节(对于32位机器取一个字节的消耗和4个字节一样),然后判断第一个字节(因为使用了寄存器,那么第一个字节就在最低位,低位低字节,高位高字节),

    8 7 6 5 4

    0 x x x x 单字节

    1 1 0 x x 双字节

    1 1 1 0 x 三字节

    1 1 1 1 0四字节

    1 0 x x x多字节的话处第一个字节外其余字节以这个开头

    低位低字节,高位高字节。Unicode有两种表示一种高位在前,另外1种高位在后

    11011111,10001111

    那么结果是11001111,00001111//部分编码选择这种方式

    那么结果是00001111,11001111//目前大多数是这样的

    其实就是高低字节顺序的问题

    更多信息请参见Utf-8编码的标准文档

    上边代码对四字节处理基本忽略掉了,因为出现4字节Utf-16无法保存,所以处理也是白处理

  • 相关阅读:
    小波变换的引入,通俗易懂
    Leetcode 437. Path Sum III
    Leetcode 113. Path Sum II
    Leetcode 112 Path Sum
    Leetcode 520 Detect Capital
    Leetcode 443 String Compression
    Leetcode 38 Count and Say
    python中的生成器(generator)总结
    python的random模块及加权随机算法的python实现
    leetcode 24. Swap Nodes in Pairs(链表)
  • 原文地址:https://www.cnblogs.com/a185771876/p/2307150.html
Copyright © 2011-2022 走看看