【问题标题】:Convert ByteArray to UUID java将 ByteArray 转换为 UUID java
【发布时间】:2020-12-27 14:05:27
【问题描述】:

问题是如何将 ByteArray 转换为 GUID。

之前我将我的 guid 转换为字节数组,经过一些交易后,我需要从字节数组中返回我的 guid。我怎么做。虽然不相关,但从 Guid 到 byte[] 的转换如下

    public static byte[] getByteArrayFromGuid(String str)
    {
        UUID uuid = UUID.fromString(str);
        ByteBuffer bb = ByteBuffer.wrap(new byte[16]);
        bb.putLong(uuid.getMostSignificantBits());
        bb.putLong(uuid.getLeastSignificantBits());

        return bb.array();
    }

但是我如何将它转换回来??

我试过这个方法,但它没有返回相同的值

    public static String getGuidFromByteArray(byte[] bytes)
    {
        UUID uuid = UUID.nameUUIDFromBytes(bytes);
        return uuid.toString();
    }

任何帮助将不胜感激。

【问题讨论】:

    标签: java bytearray uuid


    【解决方案1】:

    nameUUIDFromBytes() 方法将名称转换为 UUID。在内部,它应用哈希和一些黑魔法将任何名称(即字符串)转换为有效的 UUID。

    您必须改用new UUID(long, long); 构造函数:

    public static String getGuidFromByteArray(byte[] bytes) {
        ByteBuffer bb = ByteBuffer.wrap(bytes);
        long high = bb.getLong();
        long low = bb.getLong();
        UUID uuid = new UUID(high, low);
        return uuid.toString();
    }
    

    但是由于你不需要 UUID 对象,你可以做一个十六进制转储:

    public static String getGuidFromByteArray(byte[] bytes) {
        StringBuilder buffer = new StringBuilder();
        for(int i=0; i<bytes.length; i++) {
            buffer.append(String.format("%02x", bytes[i]));
        }
        return buffer.toString();
    }
    

    【讨论】:

    • +1 解释:特别 用于散列和一些 黑魔法 :)
    • 要更具体地了解“黑魔法”(它并不能真正弄清楚到底发生了什么),请查看docs.oracle.com/javase/7/docs/api/java/util/UUID.html。也就是说,public UUID(long mostSigBits, long leastSigBits) 可以构造你想要的任何类型的 UUID。它甚至可能会生成除 1、2、3 或 4 以外的类型的无效 UUID——但我尚未对此进行验证。 nameUUIDFromBytes 只会构造一个 3 类 UUID。
    • 可以确认@DavidJ. 的评论。我刚刚从 huxi (github.com/huxi/sulky/tree/master/sulky-ulid) 的 ULID 创建了一个 java.util.UUIDtoString() 工作正常。注意:这一切都在 JDK11 上。
    【解决方案2】:

    试试:

    public static String getGuidFromByteArray(byte[] bytes) {
        ByteBuffer bb = ByteBuffer.wrap(bytes);
        UUID uuid = new UUID(bb.getLong(), bb.getLong());
        return uuid.toString();
    }
    

    您的问题是 UUID.nameUUIDFromBytes(...) 只创建类型 3 UUID,但您需要任何 UUID 类型。

    【讨论】:

    • 如果是 8 或 16 字节就可以了。如果它有 4 个字节会发生什么。我认为它会崩溃(java.nio.bufferoverflowexception)。我们该如何解决这个问题?
    • @mindus UUID 是defined to have 128 bits (16 bytes)。如果您只有前 32 位,则无法“修复”它。如果输入是 != 16 字节,您可能想要添加输入验证并抛出 IllegalArgumentException
    【解决方案3】:

    尝试反向执行相同的过程:

    public static String getGuidFromByteArray(byte[] bytes)
    {
        ByteBuffer bb = ByteBuffer.wrap(bytes);
        UUID uuid = new UUID(bb.getLong(), bb.getLong());
        return uuid.toString();
    }
    

    对于构建和解析字节[],您确实需要考虑byte order

    【讨论】:

    • 完美。为我工作
    • 如果是 8 或 16 字节就可以了。如果它有 4 个字节会发生什么。我认为它会崩溃(java.nio.bufferoverflowexception)。我们该如何解决这个问题?
    【解决方案4】:

    编解码器BinaryCodec 可以将 UUID 编码为字节数组。

    // Convert a UUID into an array of bytes
    UuidCodec<byte[]> codec = new BinaryCodec();
    byte[] bytes = codec.encode(uuid);
    
    // Convert an array of bytes into a UUID
    UuidCodec<byte[]> codec = new BinaryCodec();
    UUID uuid = codec.decode(bytes);
    

    见:uuid-creator

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2010-10-28
      • 2014-04-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多