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

时间:2017-06-10 08:17:38

标签: java algorithm encryption hash distributed-system

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

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

1 个答案:

答案 0 :(得分:0)

你没有给出任何约束,所以一个选项是生成一个随机字符串,然后附加一个哈希值和根字符串。

例如:

  1. 基本字符串(s_i):FooBar
  2. 随机基数64字符串(r_i):( b28DGWIjI5/NeQrw5RBI9KXZ
  3. Hash[s_i || r_i]:= Hash[FooBarb28DGWIjI5/NeQrw5RBI9KXZ] = 3KGuDze1
  4. 结果= [s_i || Hash](x_i):[b28DGWIjI5/NeQrw5RBI9KXZ || 3KGuDze1] = b28DGWIjI5/NeQrw5RBI9KXZ3KGuDze1
  5. 由于散列是一个固定的长度,你可以把它拉到最后来验证它是否来自FooBar:

    1. 基本字符串(s_i):FooBar
    2. 随机字符串:b28DGWIjI5/NeQrw5RBI9KXZ3KGuDze1 = [b28DGWIjI5/NeQrw5RBI9KXZ || 3KGuDze1]
    3. 断言Hash[FoorBarb28DGWIjI5/NeQrw5RBI9KXZ] === 3KGuDze1
    4. 注意:在上面的示例中,我使用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);
          }
      }