如何将9位整数解码为一些随机4位数字

时间:2015-06-19 04:15:29

标签: java decode

如何将7位整数编码为4位数字串在java?

我有一个base36解码器,它生成6个字符,

例如:230150206转换为3T0X1A。

它的代码如下:

String f = "230150206";
int d = Integer.parseInt(f.toString());
    StringBuffer b36num = new StringBuffer();
    do {
        b36num.insert(0,(base36(d%36)));
        d = d/ 36;
    } while (d > 36);
    b36num.insert(0,(base36(d)));
    System.out.println(b36num.toString());
    }

    /**
    Take a number between 0 and 35 and return the character reprsenting
    the number. 0 is 0, 1 is 1, 10 is A, 11 is B... 35 is Z
    @param int the number to change to base36
    @return Character resprenting number in base36
    */
    private static Character base36 (int x) {
    if (x == 10) 
        x = 48;
    else if (x < 10)
        x = x + 48;
    else 
        x = x + 54;

    return new Character((char)x);
   }

有人可以与我分享一些其他方法来实现这一目标吗?

获取的字符串可以用于子字符串,但我正在寻找其他任何方法。

2 个答案:

答案 0 :(得分:1)

这是一个简单的测试程序中的方法。此方法允许任何String表示结果的数字。如初始打印所示,62位数应足以覆盖所有7位十进制数字,输出不超过4个字符,因此我推荐7位数字的十进制数字,小写字母alpha和大写字母alpha。

要覆盖四个编码数字中的9位十进制数字,您至少需要178个字符,这是仅使用7位ASCII字符无法实现的。您必须决定使用哪些附加字符作为数字。

public class Test {
  public static void main(String[] args) {
    String characters = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
    System.out.println(Math.pow(characters.length(), 4));
    testit(230150206, "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ");
    testit(230150206, characters);
  }

  private static void testit(int num, String characters){
    System.out.println(num + " "+compact(num, characters));
  }

  public static String compact(int num, String characters){
    StringBuffer compacted = new StringBuffer();
    while(num != 0){
      compacted.insert(0, characters.charAt(num % characters.length()));
      num /= characters.length();
    }
    return compacted.toString();
  }
}

输出:

1.4776336E7
230150206 3T0X1A
230150206 fzGA6

答案 1 :(得分:0)

基数10中的所有7位数字都可以容纳在24位(log2(9999999) < 24)内,即3个字节。 Ascii85需要20%的额外空间进行编码,这将使其适合4个字节。

基于Mat Banik的this answer,您可以这样做:

public class Ascii85Test {

    static int[] numbers = {
            9999999,
            490,
            7910940,
    };

    public static void main(String[] args) {
        for(int number : numbers) {
            // Convert the number into 3 bytes
            byte[] numberBytes = new byte[3];
            numberBytes[0] = (byte) ((number >> 16) & 0xFF);
            numberBytes[1] = (byte) ((number >> 8) & 0xFF);
            numberBytes[2] = (byte) (number & 0xFF);

            // Ascii85 encode the bytes
            String encoded = Ascii85Coder.encodeBytesToAscii85(numberBytes);
            // The encoded string will be "<4 characters>~\n", so we only need to keep the first 4 characters
            encoded = Ascii85Coder.encodeBytesToAscii85(numberBytes).substring(0, 4);

            // Decode them again, add the trailing ~ that we trimmed
            byte[] decodedBytes = Ascii85Coder.decodeAscii85StringToBytes(encoded + "~");

            // Convert the 3 bytes into a number
            int decodedNumber = ((decodedBytes[0] << 16) & 0xFF0000)
                    | ((decodedBytes[1] << 8) & 0xFF00)
                    | (decodedBytes[2] & 0xFF);

            System.out.printf("%s -> %s -> %s%n", number, encoded, decodedNumber);
        }
    }
}

输出:

9999999 -> R$N4 -> 9999999
490 -> !!2? -> 490
7910940 -> Gd\R -> 7910940

Java中的int最多可以包含10位数(如果计算减号,则为11位),占用4个字节。由于Ascii85的开销为20%,这意味着我们可以使用5个字符对任何整数进行编码。