Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/327.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/algorithm/10.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 如何从没有长度约束的字符串生成多个具有长度约束的随机字符串?_Java_Algorithm_Encryption_Hash_Distributed System - Fatal编程技术网

Java 如何从没有长度约束的字符串生成多个具有长度约束的随机字符串?

Java 如何从没有长度约束的字符串生成多个具有长度约束的随机字符串?,java,algorithm,encryption,hash,distributed-system,Java,Algorithm,Encryption,Hash,Distributed System,在基于java的分布式系统中,我需要从根字符串s_I创建多个随机(尽可能多的)字符串{x_I}。同时,我还需要验证字符串{x_I}是否是从s_I生成的,而不是其他根字符串。每个x_i是固定长度,s_i的长度是可变的 我怎样才能做到这一点?期待你的帮助 您不提供任何约束,因此一个选项是生成一个随机字符串,然后附加该字符串和根字符串的哈希 例如: 基本字符串(s_i):FooBar 随机基64字符串(r_i):(b28DGWIjI5/NeQrw5RBI9KXZ) Hash[s|i | r|i]:=H

在基于java的分布式系统中,我需要从根字符串s_I创建多个随机(尽可能多的)字符串{x_I}。同时,我还需要验证字符串{x_I}是否是从s_I生成的,而不是其他根字符串。每个x_i是固定长度,s_i的长度是可变的


我怎样才能做到这一点?期待你的帮助

您不提供任何约束,因此一个选项是生成一个随机字符串,然后附加该字符串和根字符串的哈希

例如:

  • 基本字符串(s_i):
    FooBar
  • 随机基64字符串(r_i):(
    b28DGWIjI5/NeQrw5RBI9KXZ
  • Hash[s|i | r|i]
    :=
    Hash[FooBarb28DGWIjI5/NeQrw5RBI9KXZ
    ] =
    3KGuDze1
  • 结果=
    [s|i|Hash]
    (x|i):[
    b28DGWIjI5/NeQrw5RBI9KXZ | 3KGuDze1
    ]=
    b28DGWIjI5/NeQrw5RBI9KXZ3KGuDze1
  • 由于散列的长度是固定的,因此可以将其从一端拉出,以验证它是否来自FooBar:

  • 基本字符串(s_i):
    FooBar
  • 随机字符串:
    b28DGWIjI5/NeQrw5RBI9KXZ3KGuDze1
    =[
    b28DGWIjI5/NeQrw5RBI9KXZ | 3KGuDze1
    ]
  • 断言
    Hash[FoorBarb28DGWIjI5/NeQrw5RBI9KXZ]
    =
    3KGuDze1
  • 注意:在上面的示例中,我使用base64编码的Sha256的前8位数字作为哈希函数

    这是系统的初稿。如果是我的系统(大型分布式系统),我会删除所有字符串转换

    public class RandomStringGenerator {
        private final int randomLength;
        private final int hashLength;
        private final MessageDigest hasher;
    
        public RandomStringGenerator(int randomLength, int hashLength, MessageDigest hasher) {
            this.randomLength = randomLength;
            this.hashLength = hashLength;
            this.hasher = hasher;
        }
    
        public String generate(String base) {
            // the multiplier accounts for the base-64 conversion
            byte[] rand = new byte[randomLength * 3 / 4];
            ThreadLocalRandom.current().nextBytes(rand);
            Base64.Encoder base64 = Base64.getEncoder();
    
            byte[] front = base64.encode(rand);
    
            hasher.update(base.getBytes(StandardCharsets.UTF_8));
            hasher.update(front);
    
            CharSequence hash = base64.encodeToString(hasher.digest()).subSequence(0, hashLength);
    
            return new String(front, StandardCharsets.UTF_8) + hash;
        }
    
        public boolean validate(String base, String random) {
            int totalLength = randomLength + hashLength;
            if (random.length() != totalLength)
                return false;
    
            String front = random.substring(0, randomLength);
            String hash = random.substring(randomLength);
    
            hasher.update(base.getBytes(StandardCharsets.UTF_8));
            hasher.update(front.getBytes(StandardCharsets.UTF_8));
    
            String calculatedHash = Base64.getEncoder().encodeToString(hasher.digest());
    
            return calculatedHash.startsWith(hash);
        }
    
        public static void main(String[] args) throws NoSuchAlgorithmException {
            MessageDigest hasher = MessageDigest.getInstance("Sha-256");
            RandomStringGenerator gen = new RandomStringGenerator(24, 8, hasher);
    
            String generated = gen.generate("FooBar");
            System.out.println(generated);
    
            boolean isValid = gen.validate("FooBar", generated);
            System.out.println("isValid: " + isValid);
        }
    }
    

    我没有得到验证部分。据我所知,给定
    x_I
    s_I
    无法确保
    x_I
    不是来自其他根字符串。随机字符串和可验证的if is from root对我来说似乎是不可能的。要么存在某种模式,因此您可以计算它是否来自同一根,要么字符串是随机的。@maraca我不同意!请参阅我的答案:一个看似随机的数字,可验证来自根字符串。@MichaelDeardeuff我认为您只是将根和随机字符串连接起来(使用唯一分隔符可能是最好的方法)。否则可能会发生冲突,不仅仅是因为散列。例如,(A,BCD),(AB,CD),(ABC,D)在串联后都给出相同的字符串。在我看来,将根和随机字符串连接起来并不是真正的随机,即使在哈希或加密之后也是如此。@maraca首先,是的,这仍然可以通过将根长度包含到哈希中来改进。其次,好的散列函数与随机函数是无法区分的。