Генерация 20 разных битов - PullRequest
       32

Генерация 20 разных битов

0 голосов
/ 19 ноября 2018

Я работаю над шифрованием с помощью DES, который использует 56-битный эффективный ключ (после отбрасывания младших значащих бит) для шифрования 64-битного открытого текста. Я хочу установить первые 20 битов ключа на случайные биты, а последние 36 битов на 0. Я пытался сделать это с BitSet, где я установил массив с 64 битами, где все значения ложны в начале. Затем я установил временный массив из 20 битов и пытался использовать bitset.set(Random.nextInt(n), true) в цикле for, который начинается с 0-20. Идея состоит в том, что я получаю ровно 20 случайных битов.

Чтобы отбросить младший значащий бит, у меня есть цикл for, в котором я перехожу от 0 до 20. В этом цикле for у меня есть оператор if, который отбрасывает каждый 8-й элемент для первых 20 элементов

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 элементов, что приводит к тому, что ключ, который я генерирую, неверен. Я несколько раз просматривал код, но не вижу, что не так.

EDIT:

Под первым и последним я подразумеваю, что первые биты являются старшими значащими битами, а последние - младшими значащими битами.

Ответы [ 2 ]

0 голосов
/ 06 февраля 2019

Как я понимаю, проблема: у вас неожиданное количество (набор) битов!

Причина: при использовании Random с заданными границами nextInt(60) и повторением 2 x 20 раз «весьма вероятно», что вы устанавливаете (перезаписываете) свои биты несколько раз, что делает вас пропущенными (set) биты к концу.

Простым решением будет повторять 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.

Более точное решение - структура данных, обеспечивающая случайные и уникальные значения ... например: Создание случайных чисел без дубликатов

или эта функция (см .: 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^^
0 голосов
/ 19 ноября 2018

Вы можете использовать битовые маски с оператором & (побитовое и):

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
...