我使用“One time Pad”实现加密,返回是我的数据库不喜欢的字符串
java.sql.SQLException:来自服务器的常规错误消息:“字符串值不正确:'\ xC2 \ x9C \ xC2 \ x98u \ xC2 ...'
public String encrypt(String message, String key) {
if (message.length() != key.length()) error("Lengths must be equal");
int[] im = charArrayToInt(message.toCharArray());
int[] ik = charArrayToInt(key.toCharArray());
int[] data = new int[message.length()];
for (int i=0;i<message.length();i++) {
data[i] = im[i] + ik[i];
}
return new String(intArrayToChar(data));
}
private int chartoInt(char c) {
return (int) c;
}
private char intToChar(int i) {
return (char) i;
}
private int[] charArrayToInt(char[] cc) {
int[] ii = new int[cc.length];
for(int i=0;i<cc.length;i++){
ii[i] = chartoInt(cc[i]);
}
return ii;
}
private char[] intArrayToChar(int[] ii) {
char[] cc = new char[ii.length];
for(int i=0;i<ii.length;i++){
cc[i] = intToChar(ii[i]);
}
return cc;
}
如何更改上面的代码,以便我可以将输出字符串插入到我的数据库中 不改变字符串的长度?
答案 0 :(得分:0)
String类型旨在表示文本。 String的实际内容是16位值的序列,表示编码为UTF-16 / UCS-2的文本。虽然UTF-16是16位值的序列,但它不是 16位值的任何序列。特别地,存在16位值的子范围,其被保留用于表示大于或等于2 16 的代码点。这些值成对使用 - 称为代理对。如果你有这些字符中的一个并且没有跟随第二个这样的字符,那么字符串也不是格式良好的UTF-16 ......并且不能转码为UTF-8。
基本上,您的方法不正确。 char
值的任意序列无法转换为UTF-8 ...或实际上转换为任何字符集。
您有两种选择:
将“encrypted”存储在数据库中作为BLOB或字节数组(如果支持)。换句话说,更改数据库列类型。
将char
值数组映射到byte
数组,然后使用十六进制或base64或其他一些强大的二进制文本编码方案对字节进行编码。这将(不可避免地)使“加密”字符串比原始字符串更长。
AFAIK,没有其他实用选择。