注意:我已尽力了解您的问题。但是抱歉,我的英语有些差。耐心一点!如有任何疑问,请评论我。提前致谢
我已经在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ὥì£ὥ
上层方法返回
length
或length * 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。