注意:我已尽力了解您的问题。但是抱歉,我的英语有些差。耐心一点!如有任何疑问,请评论我。提前致谢

我已经在Java中实现了加密算法。现在,我想测量加密前后的消息大小(以字节为单位)。

如何获取以字节为单位的文本大小?

例如,如果我有一个简单的文本Hi! I am alphanumeric (8÷4=2)

我已尽力而为,但没有找到最佳解决方案。

String temp = "Hi! I am alphanumeric (8÷4=2)"
temp.length() // this works because in ASCII every char takes one byte

// and in java every char in String takes two bytes so multiply by 2
temp.length() * 2

// also String.getBytes().length and getBytes("UTF-8").length
// returns same result


但是在我的情况下,消息解密后,字符变成了ASCII和Unicode的混合体。

例如QÂʫPǒ!qÚy¦\dὥì£ὥ

上层方法返回lengthlength * 2

但是我想计算实际字节(不是在JVM中)。例如,char a通常占用一个字节,而Unicode 例如占用两个字节。

那么如何在Java中实现此技术。

我想要一些喜欢本网站http://bytesizematters.com/中使用的技术

尽管文本的长度为22,但它却为我提供了26 bytes

注意:我希望字节作为通用字节而不是根据JVM的存储方式

最佳答案

请注意:String用于Unicode文本(能够混合所有类型的脚本),而char是两个字节的UTF-16。

这意味着二进制数据byte[]需要知道其编码/字符集,并将其转换为String。

byte[] b = ...
String s = ...
b = s.getBytes(StandardCharsets.UTF_8);
s = new String(b, StandardCharsets.UTF_8);


如果没有显式的字节字符集,则采用平台默认值,它将提供不可移植的代码。

UTF-8将允许所有文本,不仅是某些脚本,还可以是希腊文,阿拉伯文和日文。

但是,由于涉及到转换,因此非文本二进制数据可能会损坏,不是合法的UTF-8,将花费两倍的内存,并且由于转换而变慢。

因此,不惜一切代价避免将String用于二进制数据。

要回答您的问题:


您可能会被StandardCharsets.ISO_8859_1拒之门外-这是一个单字节编码。
尽管String.getBytes(StandardCharsets.ISO_8859_1).length()是两个字节,但String可能会使用两倍的内存,因此String.length()将与char对应。


字符串的替代:


byte[]本身提供了实用功能,例如Arrays
arrayEquals
ByteArrayInputStream, ByteArrayOutputStream可以包装ByteBuffer;可以读写short / int / ...
使用byte[]byte[]转换为Base64字符串。




将字节转换为一些字符

目的是将字节转换为可显示在GUI文本字段中的可见符号,并且其中char的长度与原始字节的数量相同。

例如,Lucida Sans Unicode字体的U + 2400符号代表ASCII控制字符。对于第8位的字节,可以使用西里尔字母,尽管由于西里尔字母Base64.getEncoder().encode(bytes)和拉丁文е的相似性可能会引起混淆。

static char byte2char(byte b) {
    if (b < 0) { // -128 .. -1
        return (char)(0x400 - b);
    } else if (b < 32) {
        return (char)(0x2400 + b);
    } else if (b == 127) {
        return '\u25C1';
    } else {
        return (char) b;
    }
}


e是Unicode的UTF-16编码,但在这里也对应于Unicode代码点(int)。

一个字节是有符号的,因此范围是-128到127。

09-03 20:57
查看更多