UTF-8 十六进制到 unicode 代码点(仅数学)

问题描述 投票:0回答:2

让我们使用此表,其中包含 Unicode 和 UTF-8 中的字符和十六进制编码。
有谁知道如何仅使用数学运算将 UTF-8 十六进制转换为 Unicode 代码点?
例如。我们来看第一排。给定

227
129
130
如何得到
12354

有没有只使用数学运算的简单方法?

Unicode 代码点 UTF-8 查尔
30 42 (12354) e3 (227) 81 (129) 82 (130)
30 44 (12356) e3 (227) 81 (129) 84 (132)
30 46 (12358) e3 (227) 81 (129) 86 (134)

* 来源:https://www.utf8-chartable.de/unicode-utf8-table.pl?start=12288&unicodeinhtml=hex

math unicode utf-8 hex
2个回答
7
投票

这个视频是完美的源代码(从6:15开始观看),但这里是它的摘要和golang代码示例。我用字母标记从 UTF-8 字节中获取的位,希望它有意义。当您理解逻辑时,很容易应用按位运算符):

字节 查尔 UTF-8 字节 Unicode 代码点 说明
1 字节 (ASCII) E 1. 0xxx xxxx
0100 0101
0x45
1. 0xxx xxxx
0100 0101 或
U+0045
无需转换,UTF-8 和 unicode 代码点的值相同
2 字节 Ê 1. 110x xxxx
2。 10yy yyyy
1100 0011 1000 1010
0xC38A
0xxx xxyy yyyy
0000 1100 1010 或
U+00CA
1.第一个字节的前 5 位
2。第二个字节的前 6 位
3 字节 1. 1110 xxxx
2。 10 年 yyyy
3。 10zz zzzz
1110 0011 1000 0001 1000 0010
0xE38182
xxxx yyyy yyzz zzzz
0011 0000 0100 0010 或
U+3042
1.第一个字节的前 4 位
2。第二个字节的前 6 位
3。第 3 个字节的前 6 位
4 字节 𐄟 1. 1111 0xxx
2。 10 年 yyyy
3。 10zzzzzz
4。 10ww wwww
1111 0000 1001 0000 1000 0100 1001 1111
0xF090_849F
000x xxyy yyyy zzzz zzww wwww
0000 0001 0000 0001 0001 1111 或
U+1011F
1.第一个字节的前 3 位
2。第二个字节的前 6 位
3。第三个字节的前 6 位
4。第 4 个字节的前 6 位

2 字节 UTF-8

func get(byte1 byte, byte2 byte) {
    int1 := uint16(byte1 & 0b_0001_1111) << 6
    int2 := uint16(byte2 & 0b_0011_111)
    return rune(int1 + int2)
}

3 字节 UTF-8

func get(byte1 byte, byte2 byte, byte3 byte) {
    int1 := uint16(byte1 & 0b_0000_1111) << 12
    int2 := uint16(byte2 & 0b_0011_111) << 6
    int3 := uint16(byte3 & 0b_0011_111)
    return rune(int1 + int2 + int3)
}

4 字节 UTF-8

func get(byte1 byte, byte2 byte, byte3 byt3, byte4 byte) {
    int1 := uint(byte1 & 0b_0000_1111) << 18
    int2 := uint(byte2 & 0b_0011_111) << 12
    int3 := uint(byte3 & 0b_0011_111) << 6
    int4 := uint(byte4 & 0b_0011_111)
    return rune(int1 + int2 + int3 + int4)
}

0
投票

从出色的 mihails.kuzmins 答案开始,我编写了这个 java 程序。

public class Utf {

    
    public static String utf8ToUnicode(final String utf8)  {
  
        long norma = Long.parseLong(utf8, 16);   
        
        if (norma < 256) {} 
        
        else if (norma < 65536) norma -= 49280;
        
        else if (norma < 16777216) norma -= 14712960;  
        
        else norma -= 4034953344l;

        int shift = 1; int div = 256;
        
        long remainder;
                
        long unicode = 0;
        
        while (norma > 0) {
            
            remainder = (norma % div);
            
            norma -= remainder;
            
            unicode += remainder / shift;
            
            shift *= 4; div *= 256;   
        }
        
        return Long.toHexString(unicode);
    }
    
    public static void main(String[] args) {
        
        System.out.println(utf8ToUnicode("c3a3"));        
        
    }
    
}
© www.soinside.com 2019 - 2024. All rights reserved.