【问题标题】:Generate 20 different bits生成 20 个不同的位
【发布时间】:2018-11-19 00:30:56
【问题描述】:

我正在使用 DES 进行加密,它使用 56 位有效密钥(在丢弃最低有效位之后)加密 64 位明文。我想将密钥的前 20 位设置为随机位,将后 36 位设置为 0。我一直在尝试使用 BitSet 来执行此操作,其中我设置了一个 64 位的数组,其中所有这些值在开始时是错误的。然后我设置了一个 20 位的临时数组,我一直在尝试在 for 循环中使用 bitset.set(Random.nextInt(n), true),它从 0 到 20 - 我的想法是我得到正好 20 个随机位。

为了丢弃最低有效位,我有一个从 0 到 20 的 for 循环。在这个 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 个元素,这导致我生成的密钥是错误的。我已经通过代码多次,但我看不出有什么问题。

编辑:

我所说的第一个和最后一个是指第一位是最高有效位,最后一位是最低有效位。

【问题讨论】:

  • @Kartik,这是一个错字:) 编辑了 sn-p
  • 我不明白你想在这里做什么。假设你真的想要 20 位,并且假设前 36 个低位应该为零,为什么不随机生成一个 20 位数字(这可以通过Random() 的范围参数轻松完成Java 中的方法,只需传递 2^20),然后左移 36 位?这应该需要大约 3 行代码来实现。
  • @RobertHarvey:丢弃最低有效位后,我希望最后 36 位为零,所以我有一个 56 位密钥,其中前 20 位是随机生成的,最后 36 位是是零
  • @Bab 编辑您的问题以解释这一点。
  • 请清楚您所说的“第一”和“最后”是什么意思。使用术语“最重要”和“最不重要”,而不是“第一个和最后一个”(我们不知道您从单词的哪个结尾开始计算位)。

标签: java bit bitset des


【解决方案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

【讨论】:

  • 如果我想在 DES 中使用 v2,是否必须将 v2 放入 64 位的 BitSet 中,因为高位是随机的?
  • 当使用随机时,有时我得到的高位为 20 位的低于 64 位
  • 不要使用new java.util.Random - 使用java.security.SecureRandom。当然,可能会有一些前导零位 - 如果这 20 位事件返回零,它仍然可以是随机的(平均每百万次会发生一次)
【解决方案2】:

据我了解问题:您的(设置)位数量意外!

原因:使用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^^

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-02-21
    • 2022-01-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-01-04
    相关资源
    最近更新 更多