【问题标题】:Converting number to string without losing memory在不丢失内存的情况下将数字转换为字符串
【发布时间】:2018-02-09 11:00:46
【问题描述】:

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

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

【问题讨论】:

    标签: string casting jwt long-integer


    【解决方案1】:

    这基本上是序列化。将 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 中对其进行编码。根据输入的大小、数字的性质(例如,它们是否倾向于在某个范围内)和压缩算法,您可能或多或少会成功,但如果数字随机分布在整个范围内很长的数字,你可能无法压缩很多。

    【讨论】:

    • +1 以获得真正简洁的答案以及对现有 SO 问题的信用/参考,您的解决方案是从中得出的。
    • @jdehesa,我想,你不建议将它作为一个整体对象(长数组)序列化,只是因为它不那么紧凑?还是我在这里遗漏了什么。
    • @eddyP23 好吧,我假设您想要一些简单且可互操作的格式。我不能说标准 Java 序列化会引入多少开销,尽管它没有针对大小进行优化(并且它必须存储额外的信息,例如数组的大小)。您也可以查看other serialization libs,如Kryo。无论如何,如果您使用二进制序列化,则需要一些与文本兼容的编码。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-09-11
    • 1970-01-01
    • 1970-01-01
    • 2023-03-12
    • 2011-04-28
    相关资源
    最近更新 更多