java仿php的ord_Java:PHP的ord()的实现产生了超出ASCII的字符的不同结果

我正在尝试编写一个相当于PHP的EDCOX1第0章的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中),这似乎很有效。但是,对于扩展的ASCII表或更高的表中的字符,php返回195(及更高版本)。Llama先生对相关问题的答案的评论解释如下:

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+0E9)在PHP中给出EDCOX1,2,而我的Java函数产生EDCOX1〔6〕。

ord('?')(U+2E06)在PHP中给出EDCOX1,8,而我的Java函数产生EDCOX1〔9〕。

我试图通过首先将String转换为byte数组(显式使用utf-8编码)来获得接受String的方法的相同行为:

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似乎是正确的;233确实是EDCOX1的代码0个:ASCII CODEM.195是Ã的代码,所以谁知道wtf是在php中进行的。

事实上,似乎与此密切相关:stackoverflow.com/questions/35575721/ord不适用于ut‌&諾8203;f-8

@OliverCharlesworth是正确的,PHP的ord()不能正确地处理ASCII范围之外的字符。然而,我正试图复制这种行为。

在爪哇中,EDCOX1×0是UTF 16编码单元。将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;

}

将char转换为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;

}

您可能还想读取什么是unicode、utf-8、utf-16?获取一些背景信息。

啊,这解释了一切!回答很好,谢谢。我现在使用Java大约3年了,从来没有知道它在内部使用UTF16。我会仔细阅读链接的参考资料。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值