2017-08-31 55 views
0

因此,一个长(在Java中说)为8个字节大小,并且可以存储相当大的数字。我想将它转换为字符串,但不会丢失内存。基本上需要100个数字(800字节),将它们转换为一个字符串(即接近800字节),然后当我需要它将其转换回数组。数转换为字符串,而不会失去记忆

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

回答

2

这基本上是序列化。转储长值到字节数组,然后将其编码成相容表示,如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编码它之后。根据输入的大小,数字的性质(例如它们是否处于一定范围内)以及压缩算法,您可能会获得更多或更少的成功,但是如果数字随机分布在整个范围内长数字你可能无法压缩很多。

+0

+1为真正的回答言简意赅和信用/参照从您的溶液吸入现有的SO问题。 –

+0

@jdehesa,我认为,你不是建议将它连续化为一个整体对象(long数组),仅仅因为它不是紧凑的?或者我在这里错过了一些东西。 – eddyP23

+1

@ eddyP23好吧,我假设你想要一些简单和可互操作的格式。我不能说标准的Java序列化引入了多少开销,虽然它没有针对大小进行优化(并且它将不得不存储额外的信息,例如数组的大小)。您还可以看看[其他序列库(https://stackoverflow.com/questions/239280/which-is-the-best-alternative-for-java-serialization)如[KRYO(https://开头github上。 COM/EsotericSoftware/KRYO)。在任何情况下,如果使用二进制序列化,则需要一些与文本兼容的编码。 – jdehesa

相关问题