3

重複の可能性:
21 文字の英数字を 16 バイトに圧縮

私は8つの数字を持っています

長さ4の文字列に変換する方法はありますか?

例えば:

入力12345678

出力AB2D

変換は正確に元に戻すことができるはずです。

32 Hex に変換しようとしましたが、まだ 5 つの数字があり0 1 O I、最終的な文字列では使用できません。良い提案はありますか?ところで、大文字のみを使用できました。

4

2 に答える 2

13

それは数学に帰着します。10 ^ 8の可能な数値を表現できる必要があり、4つの記号を使用する必要がある場合、各記号は100の異なる値を許可する必要があります。10^8^(1/4)これは8ビットバイトを使用して行うことができますがonly upper case letters could be used.、オプションがかなり制限されていることを示唆する要件があります。あなたはあなたが使うことができる100文字を決定しなければなりません、あるいはあなたはあなたが持つことができる数の範囲について仮定をしなければなりません。

ところで:ASCII以外の大文字を使用できる場合は、問題はありません。;)

26個の大文字のASCII文字、30個の128〜255の大文字と10桁の文字があるため、34個の記号も使用する必要があります。Unicodeを使用できる場合は、1898個の大文字と数字のUnicode文字があります。

との間には163個の小文字以外の文字が(char) 32あり(char) 255、これらのほとんどを使用できる場合はそれを実行できます。


可能な文字の厳選されたリストがより良い選択ですが、これは例です。

static final char[] ENCODE = new char[100];

static {
    int x = 0;
    for (char i = ' ' + 1; i < 256 && x < 100; i++)
        if (!Character.isLowerCase(i) && !Character.isWhitespace(i))
            ENCODE[x++] = i;
    assert x == ENCODE.length;
}

public static char[] encode(int n) {
    assert n >= 0 && n < 100000000;
    char[] ret = new char[4];
    for (int i = ret.length - 1; i >= 0; i--) {
        ret[i] = ENCODE[n % 100];
        n /= 100;
    }
    return ret;
}

public static int decode(char[] chars) {
    int n = 0;
    for (char ch : chars) {
        int x = Arrays.binarySearch(ENCODE, ch);
        assert x >= 0;
        n = n * 100 + x;
    }
    return n;
}

public static void main(String... args) {
    char[] chars = encode(12345678);
    System.out.println("Encoded: " + new String(chars));
    int n = decode(chars);
    System.out.println("Dencoded: " + n);
}

このフォントでは印刷できない文字を使用して印刷します:(

Encoded: -CY
Dencoded: 12345678
于 2012-10-16T09:44:30.333 に答える
1

いいえ。8桁は組み合わせが多すぎることを表します。整数が長さ4の文字列になるには、各10進数を1つの記号で表現できる必要があります。つまり、100個の記号を使用する必要があります。あなたが言うように、それは小数以上ですが、16進数には十分な文字がありません。小文字を使用できない場合は、句読点も使用できないと思います。その場合、十分なシンボルがないだけです。

于 2012-10-16T09:44:42.170 に答える