将数字转换为字符串而不会丢失内存

时间:2017-08-31 13:11:14

标签: string casting jwt long-integer

所以Long(比如java)是8字节大小,可以存储相当大的数字。我想将它转换为字符串,但不会丢失内存。基本上需要100个数字(800字节),将它们转换为字符串(接近800字节),然后当我需要它将其转换回数字数组时。

这个问题的原因是我想在我的JWT令牌中存储相当多的数字,所以如果我把它们当作字符串,那么这些数字的大小将比理想世界中的大得多。任何想法如何实现这一目标?

1 个答案:

答案 0 :(得分:2)

这基本上是序列化的。将long值转储为字节数组,然后将其编码为兼容表示形式,例如Base64

import java.util.Base64;

public String encodeLongs(long[] numbers) {
    byte[] bytes = new byte[8 * numbers.length];
    for (int i = 0; i < numbers.length; i++) {
        // Taken from https://stackoverflow.com/questions/18687772/java-converting-long-to-bytes-which-approach-is-more-efficient
        long v = numbers[i];
        int idx = i * 8;
        bytes[idx + 0] = (byte)(v >>> 56);
        bytes[idx + 1] = (byte)(v >>> 48);
        bytes[idx + 2] = (byte)(v >>> 40);
        bytes[idx + 3] = (byte)(v >>> 32);
        bytes[idx + 4] = (byte)(v >>> 24);
        bytes[idx + 5] = (byte)(v >>> 16);
        bytes[idx + 6] = (byte)(v >>>  8);
        bytes[idx + 7] = (byte)(v >>>  0);
    }
    return Base64.getEncoder().encodeToString(bytes);
}

如果您更方便,也可以返回字节数组而不是字符串。 Base64编码的开销大约是原始大小的1/3(假设您使用UTF-8或类似的编码)。请注意,如果您使用的是基于文本的格式,则通常不会有零开销,尽管您可能会调查其他编码,例如Base-122,尽管Base64具有无处不在且已在大多数语言中实现的优势

另一种选择是首先压缩字节数组(例如使用GZIP),然后在Base64中对其进行编码。根据输入的大小,数字的性质(例如,它们是否倾向于在某个范围内)和压缩算法,您可能或多或少取得成功,但如果数字是随机分布在整个范围内你可能无法压缩很多数字。