使用Java中的一组固定字母将long编码/解码为字符串

时间:2010-05-30 11:53:43

标签: java string encoding character-encoding decoding

给出一组任意字母

String range = "0123456789abcdefghijklmnopABCD#";

我正在寻找2种方法来编码/解码来自long< - >串

String s = encode( range, l );

long l = decode( range, s );

所以decode(range, encode(range, 123456789L)) == 123456789L

如果范围是“0123456789”,这是通常的编码方式。

4 个答案:

答案 0 :(得分:13)

以下代码可满足您的需求:

static long decode(String s, String symbols) {
    final int B = symbols.length();
    long num = 0;
    for (char ch : s.toCharArray()) {
        num *= B;
        num += symbols.indexOf(ch);
    }
    return num;
}
static String encode(long num, String symbols) {
    final int B = symbols.length();
    StringBuilder sb = new StringBuilder();
    while (num != 0) {
        sb.append(symbols.charAt((int) (num % B)));
        num /= B;
    }
    return sb.reverse().toString();
}
public static void main(String[] args) {
    String range = "0123456789abcdefghijklmnopABCD#";
    System.out.println(decode(encode(123456789L, range), range));
    // prints "123456789"

    System.out.println(encode(255L, "0123456789ABCDEF"));
    // prints "FF"

    System.out.println(decode("100", "01234567"));
    // prints "64"
}

请注意,这实际上是使用自定义符号集进行基本转换。

相关问题

答案 1 :(得分:1)

这只是执行基本转换的问题。只需将long转换为适当的数字基数,对应于字符串中的字符数,并使用范围字符串作为“数字”集。

例如,假设您有字符串“0123456789ABCDEF”,那么这意味着您必须转换为16进制,十六进制。如果字符串是“01234567”,那么您将转换为基数8,八进制。

result = "";
while (number > 0)
{
  result = range[(number % range.length)] + result;
  number = number / 16; //integer division, decimals discarded
}

要返回,请取第一个字符,在字符串中找到它的位置,然后将其添加到结果中。然后,对于每个后续字符,在添加下一个字符的位置之前,将当前结果乘以基数。

result = 0;
for (int i = 0; i < input.length; i++)
{
  result = result * range.length;
  result = range.indexOf(input[i])
}

答案 2 :(得分:0)

寻找Patten和matcher。这是我的代码段

private static final String LUCENE_ENCODE_ESCAPE_CHARS =“[\\ + \ - \!\(\)\:\ ^ \] \ {\} \〜\ * \?]”;

private static final String LUCENE_DECODE_ESCAPE_CHARS = "\\\\";
private static final String REPLACEMENT_STRING = "\\\\$0";

private static final Pattern LUCENE_ENCODE_PATTERN = Pattern.compile(LUCENE_ENCODE_ESCAPE_CHARS);
private static final Pattern LUCENE_DECODE_PATTERN = Pattern.compile(LUCENE_DECODE_ESCAPE_CHARS);

@Test
public void test() {

    String encodeMe = "\\ this + is ~ awesome ! ";

    String encode = LUCENE_ENCODE_PATTERN.matcher(encodeMe).replaceAll(REPLACEMENT_STRING);

    String decode = LUCENE_DECODE_PATTERN.matcher(encode).replaceAll("");

    System.out.println("Encode " + encode);
    System.out.println("Decode " + decode);
}

答案 3 :(得分:0)

此编码器将确保任何数量的符号具有相同的长度结果。

public class SymbolEncoder {

    private static final int INT_BITS = 32;
    public static String SYM_BINARY = "01";
    public static String SYM_ALPHANUM = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";

    private final String _symbols;
    private final int _symCount;
    private final int _outSize;

    /**
     * Construct an encoder that will encode numeric values as 
     * a String of symbols.
     * @param _symbols
     */
    public SymbolEncoder(String _symbols) {
        this._symbols = _symbols;
        this._symCount = _symbols.length();
        // calculate the number of symbols needed to encode a 32-bit int
        this._outSize = calcSymbols(INT_BITS, this._symCount);
    }

    /**
     * Calculate the number of symbols needed to encode.
     * @param _bits Number of bits to be encoded.
     * @param _symCount Number of symbols to encode.
     * @return
     */
    private static int calcSymbols(int _bits, int _symCount) {
        return (int)(_bits*Math.log(2)/Math.log(_symCount));
    }

    public String encodeFloat(float _val) {
        return encodeInt(Float.floatToIntBits(_val));
    }

    public String encodeInt(int _val) {
        StringBuilder _sb = new StringBuilder();
        int _input = _val;

        for(int _idx = 0; _idx < this._outSize; _idx++) {
            // get the current symbol
            int _symbolIdx = Integer.remainderUnsigned(_input, this._symCount);
            char _symbol = this._symbols.charAt(_symbolIdx);
            _sb.append(_symbol);

            // shift the symbol out of the input
            _input = _input / this._symCount;
        }

        return _sb.reverse().toString();
    }
}

测试用例:

SymbolEncoder _bEncode = new SymbolEncoder(SymbolEncoder.SYM_BINARY);
LOG.info("MIN_VALUE: {}", _bEncode.encodeInt(Integer.MIN_VALUE));
LOG.info("MAX_VALUE: {}", _bEncode.encodeInt(Integer.MAX_VALUE));

SymbolEncoder _alnEncode = new SymbolEncoder(SymbolEncoder.SYM_ALPHANUM);
LOG.info("MIN_VALUE: {}", _alnEncode.encodeFloat(Float.MIN_VALUE));
LOG.info("Zero: {}", _alnEncode.encodeFloat(0));
LOG.info("MAX_VALUE: {}", _alnEncode.encodeFloat(Float.MAX_VALUE));

结果:

MIN_VALUE: 10000000000000000000000000000000
MAX_VALUE: 01111111111111111111111111111111
MIN_VALUE: 000001
Zero: 000000
MAX_VALUE: ZDK8AN