Java – Apache Kafka 客户端 UUID 输入与输出不同

huangapple go评论90阅读模式
英文:

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() or fromString() 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.

huangapple
  • 本文由 发表于 2023年7月27日 23:40:37
  • 转载请务必保留本文链接:https://go.coder-hub.com/76781405.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定