Java:PHP 的 ord() 的实现对于 ASCII 之外的字符产生不同的结果

标签 java php character-encoding

我正在尝试编写一个与 PHP 的 ord() 等效的 Java 代码:

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 内。但是,PHP 返回 195 (及更高)适用于扩展 ASCII 表或其他表中的字符。 Mr. Llama 的评论至 the answer on a related question解释如下:

To elaborate, the reason é showed ASCII 195 is because it's actually a two-byte character (UTF-8), the first byte of which is ASCII 195. – Mr. Llama

因此我改变了我的ord(char c)屏蔽除最高有效字节之外的所有字节的方法:

public static int ord(char c) {
    return (int) (c & 0xFF);
}

尽管如此,结果还是有所不同。两个例子:

  • ord('é') (U+00E9) 给出 195在 PHP 中,而我的 Java 函数产生 233
  • ord('⸆') (U+2E06) 给出226在 PHP 中,而我的 Java 函数产生 6

对于接受 String 的方法,我设法获得相同的行为 首先转动String进入byte数组,显式使用 UTF-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无论如何在我的平台上。所以...

  • 如何使我的函数的行为类似于 PHP 的函数?
  • 为何更改为 ord(String s)真的有效吗?

非常感谢解释性答案,因为我想准确了解到底发生了什么。

最佳答案

在 Java 中 char is a UTF-16 code unit 。将UTF-16转换为UTF-8不仅仅是&0xFF,例如UTF-16中的01FF在UTF-8中是C7 BF,因此 PHP ord() 应该给出 0xC7 (199),而 0x01FF & 0xFF 则是 255。

String 版本可以工作,因为它实际上正在转换为 UTF-8。

最简单的方法是反转两个重载,因为 String 有一个方便的方法来获取 UTF-8:

public static int ord(String s) {
    return s.length() > 0 ? (s.getBytes(StandardCharsets.UTF_8)[0] & 0xff) : 0;
}

convert the char to a String :

public static int ord(char c) {
    return c < 0x80 ? c : ord(Character.toString(c))
}

虽然这有效,但由于不必要的 char→String→int 转换,效率不高。 Unicode 代码点 c 的 UTF-8 编码的第一个字节实际上可以使用以下命令找到:

if (c < 0x80) {
    return c;
} else if (c < 0x800) {
    return 0xc0 | c >> 6;
} else if (c < 0x10000) {
    return 0xe0 | c >> 12; 
} else {
    return 0xf0 | c >> 18;
}

您可能还想阅读What is Unicode, UTF-8, UTF-16?了解一些背景信息。

关于Java:PHP 的 ord() 的实现对于 ASCII 之外的字符产生不同的结果,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43482364/

相关文章:

mysql - 导出的 blob 数据不同于数据库数据

php - 数组创建德语问题

java - springboot 升级后 @JsonProperty 不工作

php - 使用 libressl 构建 php 7

php - 我的 php 代码有问题,我需要为我的数据库划分函数

php - 在浏览器上录制视频并上传到 LAMP 服务器

java - 为什么一个汉字需要一个字符(2 个字节)而不是 3 个字节?

java - 如何使用 wicket 将大文件上传到 google cloud

javax.xml.bind.UnmarshalException : unexpected element (uri :"", 本地 :"id")。预期元素是(无)

java - Opencv 使用套接字将 mat 从 java 发送到 python