我正在使用DES进行加密,该加密使用56位有效密钥(丢弃了最低有效位之后)来加密64位明文。我想将密钥的前20位设置为随机位,将后36位设置为0。我一直在尝试使用BitSet
进行设置,其中我建立了一个64位数组开头的所有值均为假。然后,我设置了一个20位的临时数组,并尝试在for循环(范围从0到20)中使用bitset.set(Random.nextInt(n), true)
-我的想法是我可以得到20个随机位。>
为了丢弃最低有效位,我有一个for循环,从0到20。在此for循环中,我有一个if语句,该语句丢弃前20个元素的每8个元素
static BitSet key1 = new BitSet(64);
static BitSet key2 = new BitSet(64);
public static void generate() {
BitSet temp1 = new BitSet(20);
BitSet temp2 = new BitSet(20);
Random r = new Random();
for (int i = 0; i < 20; i++) {
temp1.set(r.nextInt(60), true);
temp2.set(r.nextInt(60), true);
}
for (int i = 0; i < 20; i++) {
key1.set(i, temp1.get(i));
key2.set(i, temp2.get(i));
}
System.out.println(k1temp);
for (int i = 0; i < temp1.length(); i++) {
if (i % 8 == 0) {
key1.clear(i);
key2.clear(i);
}
}
}
因此,我的问题是我的BitSet
并不总是由20个元素组成,这导致我生成的密钥是错误的。我已经看过几次代码了,但是看不到什么地方出了错。
编辑:
我的意思是第一个和最后一个是最高有效位,最后一个是最低有效位。
答案 0 :(得分:1)
您可以通过&(按位和)运算符使用位掩码:
Random r = new SecureRandom(); // WARNING - use SecureRandom when generating cryptographic keys!
long v1 = r.nextLong() & 0xfffff; // Low order 20 bits are random, rest zero
long v2 = r.nextLong() & 0xfffff00000000000L; // High order 20 bits are random
答案 1 :(得分:0)
据我所知,问题:您有(设置)位数的意外计数!
原因:使用Random
,在给定范围nextInt(60)
下,重复2 x 20次,您很有可能多次设置(覆盖)位,这使您在末尾丢失(设置)位。
一个简单的解决方案是将int next = nextInt(60);
重复到!temp1.get(next)
(分别temp2
):
Random r = new Random();
for (int i = 0; i < 20; i++) {
int next = r.nextInt(60);
while (temp1.get(next)) { //bit already set, repeat:
next = r.nextInt(60);
}
temp1.set(next);
// temp2:
next = r.nextInt(60);
while (temp2.get(next)) {
next = r.nextInt(60);
}
temp2.set(next);
} // ensures you 20 bits set.
一个更好的解决方案是数据结构,它可以确保您获得随机且唯一的值,例如:Creating random numbers with no duplicates
或此功能(请参见:https://stackoverflow.com/a/54608445/592355):
static IntStream uniqueInts(int min, int max, int count, java.util.Random rnd) {
// call Random.ints(min, max) with ... distinct and limit
return rnd.ints(min, max).distinct().limit(count);
}
您将使用以下方式:
final BitSet temp1 = new BitSet(20); // values lower than 64 (resp. 32?) lead to 64 (resp. 32!)
final BitSet temp2 = new BitSet(20);
final Random r = new Random();
unniqueInts(0, 60, 20, r).forEach(i - > {if(i % 8 > 0)temp1.set(i)});
unniqueInts(0, 60, 20, r).forEach(i - > {if(i % 8 > 0)temp2.set(i)});
//also better:
key1.or(temp1);
key2.or(temp2);
System.out.println(k1temp);
//the if (i % 8 == 0) ..already done in forEach^^