英文:
Java - Apache kafka-client Uuid input differs from output
问题
我需要指定kafka_cluster_ids,并在测试字符串时使用org.apache.kafka.common.Uuid
类的fromString
方法时注意到生成的Uuid
的最后一个字符与输入字符串不同,但如果使用Uuid.toString
返回的字符串来创建另一个Uuid
,输入和输出将相同。
import org.apache.commons.text.CharacterPredicates;
import org.apache.commons.text.RandomStringGenerator;
import org.apache.kafka.common.Uuid;
public class Main {
public static void main(String[] args) {
RandomStringGenerator rsg = new RandomStringGenerator.Builder()
.withinRange('0', 'z')
.filteredBy(CharacterPredicates.LETTERS, CharacterPredicates.DIGITS)
.build();
String unique = rsg.generate(22);
System.out.println(unique); // 输出 MHAQTegTj687qceJKFx0gB
Uuid id = Uuid.fromString(unique);
System.out.println(id); // 输出 MHAQTegTj687qceJKFx0gA
Uuid id2 = Uuid.fromString(id.toString());
System.out.println(id2); // 输出 MHAQTegTj687qceJKFx0gA
}
}
这只是一个小问题,但让我感到有点困扰。我想知道为什么最后一个字符会改变。提前感谢您!
编辑:供参考,Uuid
中的相关源代码:
/**
* 返回UUID的base64字符串编码。
*/
@Override
public String toString() {
return Base64.getUrlEncoder().withoutPadding().encodeToString(getBytesFromUuid());
}
/**
* 基于toString()方法中使用的base64字符串编码创建UUID。
*/
public static Uuid fromString(String str) {
if (str.length() > 24) {
throw new IllegalArgumentException("输入字符串以前缀 `" + str.substring(0, 24) + "` 太长,无法解码为base64 UUID");
}
ByteBuffer uuidBytes = ByteBuffer.wrap(Base64.getUrlDecoder().decode(str));
if (uuidBytes.remaining() != 16) {
throw new IllegalArgumentException("输入字符串 `" + str + "` 解码为 "
+ uuidBytes.remaining() + " 字节,这与base64编码的UUID的预期16字节不相等");
}
return new Uuid(uuidBytes.getLong(), uuidBytes.getLong());
}
private byte[] getBytesFromUuid() {
// 提取UUID的字节,长度为128位(或16字节)。
ByteBuffer uuidBytes = ByteBuffer.wrap(new byte[16]);
uuidBytes.putLong(this.mostSignificantBits);
uuidBytes.putLong(this.leastSignificantBits);
return uuidBytes.array();
}
英文:
I need to specify kafka_cluster_ids, and when testing strings with the org.apache.kafka.common.Uuid
class' fromString
method, I noticed that the last character of the resulting Uuid
differs from the input string, but if you use the string returned by Uuid.toString
to create another Uuid
, the input and output are the same.
import org.apache.commons.text.CharacterPredicates;
import org.apache.commons.text.RandomStringGenerator;
import org.apache.kafka.common.Uuid;
public class Main {
public static void main(String[] args) {
RandomStringGenerator rsg = new RandomStringGenerator.Builder()
.withinRange('0', 'z')
.filteredBy(CharacterPredicates.LETTERS, CharacterPredicates.DIGITS)
.build();
String unique = rsg.generate(22);
System.out.println(unique); // prints MHAQTegTj687qceJKFx0gB
Uuid id = Uuid.fromString(unique);
System.out.println(id); // prints MHAQTegTj687qceJKFx0gA
Uuid id2 = Uuid.fromString(id.toString());
System.out.println(id2); // prints MHAQTegTj687qceJKFx0gA
}
}
It's a minor thing, but it bugs me a bit. I'd like to know why that last character is changing. Thanks in advance!
Edit: For reference, the relevant source code from Uuid
:
/**
* Returns a base64 string encoding of the UUID.
*/
@Override
public String toString() {
return Base64.getUrlEncoder().withoutPadding().encodeToString(getBytesFromUuid());
}
/**
* Creates a UUID based on a base64 string encoding used in the toString() method.
*/
public static Uuid fromString(String str) {
if (str.length() > 24) {
throw new IllegalArgumentException("Input string with prefix `"
+ str.substring(0, 24) + "` is too long to be decoded as a base64 UUID");
}
ByteBuffer uuidBytes = ByteBuffer.wrap(Base64.getUrlDecoder().decode(str));
if (uuidBytes.remaining() != 16) {
throw new IllegalArgumentException("Input string `" + str + "` decoded as "
+ uuidBytes.remaining() + " bytes, which is not equal to the expected 16 bytes "
+ "of a base64-encoded UUID");
}
return new Uuid(uuidBytes.getLong(), uuidBytes.getLong());
}
private byte[] getBytesFromUuid() {
// Extract bytes for uuid which is 128 bits (or 16 bytes) long.
ByteBuffer uuidBytes = ByteBuffer.wrap(new byte[16]);
uuidBytes.putLong(this.mostSignificantBits);
uuidBytes.putLong(this.leastSignificantBits);
return uuidBytes.array();
}
答案1
得分: 1
Apache kafka-client Uuid input differs from output (usage of
toString()
orfromString()
methods)
在Kafka 2.6.x之前使用的Kafka库中,UUID类的toString()
方法返回的字符串格式是xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
,其中每个x
代表一个十六进制数字。这是我经验中最常见的UUID格式。
然而,从Kafka 2.6.x开始,UUID类的toString()
方法返回的字符串格式是xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
,其中每个x
代表一个十六进制数字。这种格式被称为规范格式的UUID格式。如何进行转换?请参见此处。
英文:
> Apache kafka-client Uuid input differs from output (usage of toString()
or fromString()
methods)
Different UUID formats in short, depending to the version of used artifact in Kafka prior to 2.6.x the toString()
method of the UUID class returned a string in the format xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
, where each x
represents a hexadecimal digit. Which is most common UUID format in my experiences.
However, from Kafka 2.6.x, the toString()
method of the UUID class returns a string in the format xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
where each x
represents a hexadecimal digit. This format is known as the canonical UUID format, how convert them ? see here.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论