我正在尝试编写与PHP的ord()
:
public static int ord(char c) {
return (int) c;
}
public static int ord(String s) {
return s.length() > 0 ? ord(s.charAt(0)) : 0;
}
这似乎适用于序数值高达127
的字符,即ASCII内。但是,对于扩展ASCII表或更高版本的字符,PHP返回195
(和更高)。 Mr. Llama对the answer on a related question的评论解释如下:
详细说明,原因é显示ASCII 195是因为它实际上是一个双字节字符(UTF-8),其第一个字节是ASCII 195. - Llama先生
因此我改变了我的ord(char c)
方法来屏蔽掉除最重要字节之外的所有字节:
public static int ord(char c) {
return (int) (c & 0xFF);
}
然而,结果不同。两个例子:
ord('é')
(U + 00E9)在PHP中提供195
,而我的Java函数产生233
ord('⸆')
(U + 2E06)在PHP中提供226
,而我的Java函数产生6
我通过首先将String
转换为String
数组,显式地使用UTF-来接受byte
的方法,以获得相同的行为 8编码:
public static int ord(String s) {
return s.length() > 0 ? ord((char)s.getBytes(StandardCharsets.UTF_8)[0]) : 0;
}
但是,使用接受char
的方法仍然像以前一样,我还无法找到解决方案。另外,我不明白为什么更改确实有效:Charset.defaultCharset()
无论如何都会在我的平台上返回UTF-8
。所以......
ord(String s)
的更改确实有效? 非常感谢解释性答案,因为我想要了解究竟发生了什么。
答案 0 :(得分:3)
在Java中char
is a UTF-16 code unit。将UTF-16转换为UTF-8不仅仅是& 0xFF
,例如UTF-16中的01FF
在UTF-8中是C7 BF
,因此PHP ord()
应该给{ {1}}(199),但0xC7
为255。
0x01FF & 0xFF
版本有效,因为它实际上正在转换为UTF-8。
最简单的方法是反转你的两个重载,因为String
有一个方便的方法来获取UTF-8:
String
和convert the char
to a String
:
public static int ord(String s) {
return s.length() > 0 ? (s.getBytes(StandardCharsets.UTF_8)[0] & 0xff) : 0;
}
虽然这有效,但由于不必要的char→String→int转换,它效率不高。可以使用以下命令实际找到Unicode代码点public static int ord(char c) {
return c < 0x80 ? c : ord(Character.toString(c))
}
的UTF-8编码的第一个字节:
c
您可能还想阅读What is Unicode, UTF-8, UTF-16?以获取一些背景信息。