在基于java的分布式系统中,我需要从根字符串s_i创建多个随机(尽可能多)字符串{x_i}。同时,我还需要验证是否从s_i生成字符串{x_i},而不是其他根字符串。每个x_i都是固定长度,s_i的长度是可变的。
我怎样才能做到这一点?期待您的帮助。
答案 0 :(得分:0)
你没有给出任何约束,所以一个选项是生成一个随机字符串,然后附加一个哈希值和根字符串。
例如:
FooBar
b28DGWIjI5/NeQrw5RBI9KXZ
)Hash[s_i || r_i]
:= Hash[FooBarb28DGWIjI5/NeQrw5RBI9KXZ
]
= 3KGuDze1
[s_i || Hash]
(x_i):[b28DGWIjI5/NeQrw5RBI9KXZ || 3KGuDze1
] = b28DGWIjI5/NeQrw5RBI9KXZ3KGuDze1
由于散列是一个固定的长度,你可以把它拉到最后来验证它是否来自FooBar:
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);
}
}