欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Java中將UUID存儲為Base64字符串的方法實現(xiàn)

 更新時間:2024年04月28日 16:36:16   作者:HoneyMoose  
使用Base64編碼來對UUID存儲在一些特定的場合被廣泛的使用,本文主要介紹了Java中將UUID存儲為Base64字符串的方法實現(xiàn),具有一定的參考價值,感興趣的可以了解一下

概述

使用 Base64 編碼來對 UUID(Universally Unique Identifiers) 存儲在一些特定的場合被廣泛的使用。使用 Base64 對比直接使用 UUID 進行存儲來說能夠更多的節(jié)約空間。

本文對這方面的相關(guān)內(nèi)容和問題進行探討。

在這里,使用 Base64 來對 UUID 進行存儲,涉及到一些類型的轉(zhuǎn)換的。Base64 是編碼算法,在實際使用的時候我們更多會用到 Byte 數(shù)組的方式來進行編碼的。這樣我們就比較明確在對其進行 Base64 轉(zhuǎn)換之前,我們應(yīng)該要先干什么了。

使用 byte[]和 Base64.Encoder

Base64.Encoder 就能夠提供 byte[] 的 Base64 編碼了,我們先使用這個最簡單的方式來進行處理。

編碼

首先我們需要給出的 UUID 位中創(chuàng)建出我們需要的 byte 數(shù)組。

我們先獲得 UUID 的 most significant bits 和 least significant bits,然后放入我們 byte 數(shù)組中的 0-7 和 8-15 的位置。

程序代碼如下:

    private byte[] convertToByteArray(UUID uuid) {
        byte[] result = new byte[16];

        long mostSignificantBits = uuid.getMostSignificantBits();
        fillByteArray(0, 8, result, mostSignificantBits);

        long leastSignificantBits = uuid.getLeastSignificantBits();
        fillByteArray(8, 16, result, leastSignificantBits);

        return result;
    }

上面的代碼中還有一個 fillByteArray 方法,這個方法,這個方法將會把我們的 bit 存如 byte array 數(shù)組中,同時還會移動 8 位。

方法的代碼如下:

void fillByteArray(int start, int end, byte[] result, long bits) {
    for (int i = start; i < end; i++) {
        int shift = i * 8;
        result[i] = (byte) ((int) (255L & bits >> shift));
    }
}

當(dāng)我們獲得 byte 數(shù)組后,我們就可以調(diào)用 JDK 的 Base64.Encoder 方法來直接進行編碼了成一個 Base64 加密字符串了。

完整的測試代碼如下:

UUID originalUUID = UUID.fromString("cc5f93f7-8cf1-4a51-83c6-e740313a0c6c");

@Test
void givenEncodedString_whenDecodingUsingBase64Decoder_thenGiveExpectedUUID() {
    String expectedEncodedString = "UUrxjPeTX8xsDDoxQOfGgw==";
    byte[] uuidBytes = convertToByteArray(originalUUID);
    String encodedUUID = Base64.getEncoder().encodeToString(uuidBytes);
    assertEquals(expectedEncodedString, encodedUUID);
}

解碼

把我們獲得的 UUID Base64 字符串進行解碼,我們可以使用完全相反的方法:

@Test
public void givenEncodedString_whenDecodingUsingBase64Decoder_thenGiveExpectedUUID() {
    String expectedEncodedString = "UUrxjPeTX8xsDDoxQOfGgw==";
    byte[] decodedBytes = Base64.getDecoder().decode(expectedEncodedString);
    UUID uuid = convertToUUID(decodedBytes);
}

首先把 Base64 字符串解碼成 Byte 數(shù)組,然后調(diào)用我們的轉(zhuǎn)換方法,把我們獲得 byte 數(shù)組轉(zhuǎn)換成為 UUID 對象。

UUID convertToUUID(byte[] src) {
    long mostSignificantBits = convertBytesToLong(src, 0);
    long leastSignificantBits = convertBytesToLong(src, 8);

    return new UUID(mostSignificantBits, leastSignificantBits);
}

在上面的方法中,我們分別對 UUID 中需要使用的 most significant bits 和 less significant bits 分別進行轉(zhuǎn)換,然后再組合在一起。

轉(zhuǎn)換的方法如下:

long convertBytesToLong(byte[] uuidBytes, int start) {
    long result = 0;

    for(int i = 0; i < 8; i++) {
        int shift = i * 8;
        long bits = (255L & (long)uuidBytes[i + start]) << shift;
        long mask = 255L << shift;
        result = result & ~mask | bits;
    }

    return result;
}

通過上面的測試代碼,可以看到代碼的轉(zhuǎn)換都順利完成了。

使用 ByteBuffer 和 Base64.getUrlEncoder()

如果我們還使用 JDK 的 API 的話,我們還可以把上面的代碼進行一些簡化。

編碼

通過使用 ByteBuffer,我們可以使用非常簡單的下面 2 行代碼把 UUID 的 bit 轉(zhuǎn)換為 buffer wrapping 數(shù)組。

ByteBuffer byteBuffer = ByteBuffer.wrap(new byte[16]);
byteBuffer.putLong(originalUUID.getMostSignificantBits());
byteBuffer.putLong(originalUUID.getLeastSignificantBits());

當(dāng)程序執(zhí)行完上面的 2 行代碼后,我們將會獲得 一個 ByteBuffer 對象,這個對象中存儲的是 UUID 轉(zhuǎn)換過來的數(shù)據(jù)。

針對編碼,我們就可以使用 Base64.getUrlEncoder() 方法,這個方法的參數(shù)我們可以使用 ByteBuffer 轉(zhuǎn)換成 array 就可以了,因為 ByteBuffer 轉(zhuǎn)換成 Array 是返回 Array 的。

String encodedUUID = Base64.getUrlEncoder().encodeToString(byteBuffer.array());

針對上面代碼的修改,我們只需要下面簡單的幾行代碼就可以完成 UUID 到 Base64 的轉(zhuǎn)換。

@Test
public void givenUUID_whenEncodingUsingByteBufferAndBase64UrlEncoder_thenGiveExpectedEncodedString() {
    String expectedEncodedString = "zF-T94zxSlGDxudAMToMbA==";
    ByteBuffer byteBuffer = ByteBuffer.wrap(new byte[16]);
    byteBuffer.putLong(originalUUID.getMostSignificantBits());
    byteBuffer.putLong(originalUUID.getLeastSignificantBits());
    String encodedUUID = Base64.getUrlEncoder().encodeToString(byteBuffer.array());
    assertEquals(expectedEncodedString, encodedUUID);
}

解碼

解碼就使用 Base64.UrlDecoder() 即可,Base64.UrlDecoder() 的解碼結(jié)果為 byte 數(shù)組,所以我們還需要用 ByteBuffer.wrap 把解碼后的數(shù)組包裝成 ByteBuffer 對象。

@Test
void givenEncodedString_whenDecodingUsingByteBufferAndBase64UrlDecoder_thenGiveExpectedUUID() {
    String expectedEncodedString = "zF-T94zxSlGDxudAMToMbA==";
    byte[] decodedBytes = Base64.getUrlDecoder().decode(expectedEncodedString);
    ByteBuffer byteBuffer = ByteBuffer.wrap(decodedBytes);
    long mostSignificantBits = byteBuffer.getLong();
    long leastSignificantBits = byteBuffer.getLong();
    UUID uuid = new UUID(mostSignificantBits, leastSignificantBits);
    assertEquals(originalUUID, uuid);
}

縮短編碼后字符串

在我們完成上面的編碼后,我們會看到字符串的最后還有 2 個等號 “==” 。為了進一步節(jié)約我們的存儲空間,我們可以把這 2 個等號從字符串中刪除。

我們可以配置編碼函數(shù),告訴編碼函數(shù)不要在字符串的末尾添加 2 個等號。

String encodedUUID = 
  Base64.getUrlEncoder().withoutPadding().encodeToString(byteBuffer.array());

assertEquals(expectedEncodedString, encodedUUID);

針對解碼的方法來說,我們并不需要對方法進行任何改變,因為現(xiàn)在的解碼方法已經(jīng)能夠正確識別 Base64 字符串的末尾是不是有 2 個等號,并且可都兼容。

使用 Apache Commons Conversion Utils 和Codec Utils 工具類

在這部分,我們使用 Apache Commons Conversion Utils 的工具類來先把 UUID 對象轉(zhuǎn)換為 UUID byte 數(shù)組,然后使用 Apache Commons Codec Utils 工具類來把進行 Base64 的字符串處理。

依賴

為了完成上面 2 個步驟,我們需要分別使用 Apache Commons Lang library 和 commons-codec 類庫

在我們的 pom.xml 項目文件中,分別添加上面 2 個類庫的依賴。

通常你的項目基本上都會包含進來的,如果沒有的話再添加。

<dependency>
    <groupId>org.apache.commons</groupId>
    <artifactId>commons-lang3</artifactId>
    <version>3.14.0</version>
</dependency>

<dependency>
    <groupId>commons-codec</groupId>
    <artifactId>commons-codec</artifactId>
    <version>1.16.0</version>
</dependency>

編碼

上面的編碼就非常簡單了,直接使用 Conversion.uuidToByteArray 方法,把要編碼的 UUID 對象傳進來,然后直接 Base64,使用 URL 安全的方法。

@Test
void givenUUID_whenEncodingUsingApacheUtils_thenGiveExpectedEncodedString() {
    String expectedEncodedString = "UUrxjPeTX8xsDDoxQOfGgw";
    byte[] bytes = Conversion.uuidToByteArray(originalUUID, new byte[16], 0, 16);
    String encodedUUID = encodeBase64URLSafeString(bytes);
    assertEquals(expectedEncodedString, encodedUUID);
}

通過上面的代碼,我們可以看到結(jié)果是 Base 64 已經(jīng)把最后的 2 個等號刪掉了。

解碼

針對解碼來說,我們使用的是 JDK 的 Base64.decodeBase64() 方法,然后調(diào)用 Conversion.byteArrayToUuid() 把解碼后的 byte 數(shù)組轉(zhuǎn)換為 UUID 對象。

@Test
void givenEncodedString_whenDecodingUsingApacheUtils_thenGiveExpectedUUID() {
    String expectedEncodedString = "UUrxjPeTX8xsDDoxQOfGgw";
    byte[] decodedBytes = decodeBase64(expectedEncodedString);
    UUID uuid = Conversion.byteArrayToUuid(decodedBytes, 0);
    assertEquals(originalUUID, uuid);
}

結(jié)論

UUID 是廣泛使用的 ID 識別標(biāo)識,我們通過對 Base64 的轉(zhuǎn)換來讓 UUID 能夠以更小的數(shù)據(jù)量來進行存儲。

轉(zhuǎn)換的關(guān)鍵就在于 UUID 先要轉(zhuǎn)換為 byte 數(shù)組,然后 Base64 是對 byte[] 數(shù)組進行編碼的。

到此這篇關(guān)于Java中將UUID存儲為Base64字符串的方法實現(xiàn)的文章就介紹到這了,更多相關(guān)Java UUID存儲為Base64內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

最新評論