RosettaCodeData/Task/Variable-length-quantity/Java/variable-length-quantity.java

60 lines
1.4 KiB
Java

public class VLQCode
{
public static byte[] encode(long n)
{
int numRelevantBits = 64 - Long.numberOfLeadingZeros(n);
int numBytes = (numRelevantBits + 6) / 7;
if (numBytes == 0)
numBytes = 1;
byte[] output = new byte[numBytes];
for (int i = numBytes - 1; i >= 0; i--)
{
int curByte = (int)(n & 0x7F);
if (i != (numBytes - 1))
curByte |= 0x80;
output[i] = (byte)curByte;
n >>>= 7;
}
return output;
}
public static long decode(byte[] b)
{
long n = 0;
for (int i = 0; i < b.length; i++)
{
int curByte = b[i] & 0xFF;
n = (n << 7) | (curByte & 0x7F);
if ((curByte & 0x80) == 0)
break;
}
return n;
}
public static String byteArrayToString(byte[] b)
{
StringBuilder sb = new StringBuilder();
for (int i = 0; i < b.length; i++)
{
if (i > 0)
sb.append(", ");
String s = Integer.toHexString(b[i] & 0xFF);
if (s.length() < 2)
s = "0" + s;
sb.append(s);
}
return sb.toString();
}
public static void main(String[] args)
{
long[] testNumbers = { 2097152, 2097151, 1, 127, 128, 589723405834L };
for (long n : testNumbers)
{
byte[] encoded = encode(n);
long decoded = decode(encoded);
System.out.println("Original input=" + n + ", encoded = [" + byteArrayToString(encoded) + "], decoded=" + decoded + ", " + ((n == decoded) ? "OK" : "FAIL"));
}
}
}