我想以下列格式加密/保护输入字符串" AB123456789000" (两个字母和12个数字),以便安全"版本"可以在数据库中以长号(数字)存储。
我已经尝试过RC2加密,但它给了我128位,不适合64位长。
答案 0 :(得分:1)
首先,我必须有点咆哮。
byte[]
上运行,无需将其表示为long
。每个数据库系统也应该能够保存二进制blob。返回将输入大小降至64位以下。
使用ASCII,您的14个字母的长字符串将是14个字节(= 112)位,如果不进行压缩,其加密将不适合64位。您可以通过说格式必须 2个字母然后12个数字来作弊。对于编码,您将在ASCII表示中逐字记录前两个字母。那将是2 * 8位= 16位。然后将12位数作为整数,例如123456789000 = 0x1cbe991a08
,即5个字节(= 40位,适合long
)。这里最大的数字是9999999999
0xe8d4a50fff
,所以一切都可以保存为5个字节。
总而言之,我们将拥有2 * 8位+ 5 * 8位= 56位,这足够小,可以适合RC2加密的一个块,即64位。您可以将最后一个字节设置为0x00
。
因此,简而言之,明文的编码版本的2个字节将代表这两个字母的ASCII值,然后接下来的5个字节将是long
的数字。
例如,
AB123456789000
将被编码为0x41421cbe991a08
('A' = 0x41, B = 0x42
,然后123456789000 = 0x1cbe991a08
)。您可以在Java和C#中编写编码和解码函数来实现这一点。
答案 1 :(得分:1)
编码到64位可以很简单:
public static long toId(String id) {
long numPart = Long.parseLong(id.substring(2));
long letterPart = Long.parseLong(id.substring(0, 2), 36);
long res = (letterPart << 40) | numPart;
System.out.println("Ids: " + id + " -> " + res);
return res;
}
public static void main(String[] args) {
toId("AB123456789000");
toId("AA000000000000");
toId("AA999999999999");
toId("ZZ000000000000");
toId("ZZ999999999999");
}
结果
Ids: AB123456789000 -> 408042270693896
Ids: AA000000000000 -> 406819302277120
Ids: AA999999999999 -> 407819302277119
Ids: ZZ000000000000 -> 1423867557969920
Ids: ZZ999999999999 -> 1424867557969919