我在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 中)。例如,chara
通常需要一个字节,而 Unicode™
则占用两个字节。
那么如何在Java中实现这种技术呢?
我想要一些喜欢这个网站中使用的技术 http://bytesizematters.com/
它让我26 bytes
这个文本QÂʫP†ǒ!‡˜q‡Úy¦dƒὥ죉ὥ
尽管文本的长度是 22。
请注意:String
用于Unicode文本(能够混合所有类型的脚本),char
是两个字节UTF-16。
这意味着二进制数据byte[]
需要知道其编码/字符集,并将转换为字符串。
byte[] b = ...
String s = ...
b = s.getBytes(StandardCharsets.UTF_8);
s = new String(b, StandardCharsets.UTF_8);
如果没有明确的字节字符集,则采用平台默认值,这将提供不可移植的代码。
UTF-8
将允许所有文本,而不仅仅是某些脚本,而是希腊语、阿拉伯语、日语。
但是,由于涉及转换,非文本二进制数据可能会损坏,不会是合法的 UTF-8,将花费双倍的内存并且由于转换而变慢。
因此,不惜一切代价避免二进制数据的字符串。
要回答您的问题:
- 您可能会通过
StandardCharsets.ISO_8859_1
逃脱 - 这是一个单字节编码。 - 然后
String.getBytes(StandardCharsets.ISO_8859_1).length()
将对应于String.length()
尽管字符串可能会使用双倍的内存,因为char
是两个字节。
字符串的替代项:
byte[]
本身,Arrays
提供实用程序函数,例如arrayEquals
。ByteArrayInputStream, ByteArrayOutputStream
ByteBuffer
可以包装byte[]
;可以读写短/整/...- 使用
Base64.getEncoder().encode(bytes)
将byte[]
转换为Base64字符串。
将一个字节转换为某个字符
目标是将字节转换为可在 GUI 文本字段中显示的可见符号,并且以字符为单位的长度与原始字节数相同。
例如,字体Lucida Sans Unicode具有代表ASCII控制字符的U + 2400符号。对于第 8 位的字节,可以采用西里尔文,但由于西里尔文е
和拉丁文e
的相似性,可能会出现混淆。
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;
}
}
char
是 Unicode 的 UTF-16 编码,但这里也对应于 Unicode 码位 (int)。
字节是有符号的,因此范围从 -128 到 127。