产生20个不同的位

时间:2018-11-19 00:30:57

标签: java bit bitset des

我正在使用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个元素组成,这导致我生成的密钥是错误的。我已经看过几次代码了,但是看不到什么地方出了错。

编辑:

我的意思是第一个和最后一个是最高有效位,最后一个是最低有效位。

2 个答案:

答案 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^^