Java:PHP'的实现;s ord()对ASCII以外的字符产生不同的结果

Java:PHP'的实现;s ord()对ASCII以外的字符产生不同的结果,java,php,character-encoding,Java,Php,Character Encoding,我正在尝试编写一个与PHP等效的Java: 这似乎适用于序号值高达127的字符,即ASCII内的字符。但是,对于扩展ASCII表或更高版本中的字符,PHP返回195(及更高版本)。to的评论解释如下: 更详细地说,显示ASCII 195的原因是因为它实际上是一个双字节字符(UTF-8),其第一个字节是ASCII 195骆驼先生 因此,我更改了我的ord(char c)方法,以屏蔽除最高有效字节以外的所有字节: public static int ord(char c) { return

我正在尝试编写一个与PHP等效的Java:

这似乎适用于序号值高达
127
的字符,即ASCII内的字符。但是,对于扩展ASCII表或更高版本中的字符,PHP返回
195
(及更高版本)。to的评论解释如下:

更详细地说,显示ASCII 195的原因是因为它实际上是一个双字节字符(UTF-8),其第一个字节是ASCII 195骆驼先生

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

public static int ord(char c) {
    return (int) (c & 0xFF);
}
尽管如此,结果还是不尽相同。两个例子:

  • ord('ee')
    (U+00E9)在PHP中给出
    195
    ,而我的Java函数则给出
    233
  • ord('⸆')(U+2E06)在PHP中给出
    226
    ,而我的Java函数则给出
    6
通过首先将
字符串
转换为
字节
数组,显式使用UTF-8编码,我成功地获得了接受
字符串
的方法的相同行为:

public static int ord(String s) {
    return s.length() > 0 ? ord((char)s.getBytes(StandardCharsets.UTF_8)[0]) : 0;
}
但是,使用接受字符的方法仍然像以前一样,我还没有找到解决方案。此外,我不明白为什么更改会起作用:
Charset.defaultCharset()
在我的平台上返回
UTF-8
。所以

  • 如何使我的函数的行为类似于PHP?
  • 为什么更改为
    ord(字符串s)
    实际起作用?
非常感谢解释性的回答,因为我想准确地掌握发生了什么。

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

字符串
版本之所以有效,是因为它实际上正在转换为UTF-8

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

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


您可能还想阅读一些背景信息。

Java似乎是正确的;233确实是
的代码:.195是
Ã
的代码,所以谁知道WTF在PHP中的运行情况。实际上,似乎与此有很大关系:@OliverCharlesworth这是正确的,PHP的
ord()
无法正确处理ASCII范围以外的字符。但是,我正在尝试复制这种行为。啊,这就解释了一切!回答得很好,谢谢。我使用Java大约3年了,从来都不知道它在内部使用UTF-16。我会确保仔细阅读链接的参考资料。
public static int ord(String s) {
    return s.length() > 0 ? (s.getBytes(StandardCharsets.UTF_8)[0] & 0xff) : 0;
}
public static int ord(char c) {
    return c < 0x80 ? c : ord(Character.toString(c))
}
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;
}