2017-06-10 8 views
0

Javaベースの分散システムでは、ルート文字列s_iから複数のランダムな(可能な限り)文字列{x_i}を作成する必要があります。一方、他のルート文字列ではなく、文字列{x_i}がs_iから生成されるかどうかを確認する必要もあります。各x_iは固定長であり、s_iの長さは可変である。長さ制約のない文字列から、長さ制約のある複数のランダムな文字列を生成する方法は?

どうすればこの問題を解決できますか?あなたの助けを楽しみにしています。

+0

私は検証部分を取得しませんでした。私が見る限りでは、 'x_i'と' s_i'を与えれば、 'x_i'が他のルート文字列から来ていないことを確認する方法がありません。 –

+1

ランダムな文字列で、ルートからのものであるかどうかを確認することは不可能です。どちらかのパターンがあるので、同じルートから来たものか、文字列がランダムであるかを評価することができます。 – maraca

+0

@maraca私は違うことを請う!私の答えを参照してください:一見乱数、ルート文字列から来ることを確認します。 –

答えて

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

ハッシュが固定長であるため、それはFooBarのから来ているかどうかを確認するために端をそれを引っ張ることができる:

  1. ベースストリング(S_I):FooBar
  2. ランダムな文字列:b28DGWIjI5/NeQrw5RBI9KXZ3KGuDze1 = [b28DGWIjI5/NeQrw5RBI9KXZ || 3KGuDze1]
  3. アサート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); 
    } 
} 
関連する問題