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

问题描述 投票:4回答:4

给出任意一组字母

String range = "0123456789abcdefghijklmnopABCD#";

我正在寻找2种方法来对长字符串进行编码/解码

String s = encode( range, l );

long l = decode( range, s );

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

并且如果范围是“ 0123456789”,那就是通常的编码方式。

java string encoding character-encoding decoding
4个回答
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
投票

这只是执行基本转换的问题。只需将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])
}

0
投票

寻找Patten和匹配器。这是我的代码段

私有静态最终字符串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);
}

0
投票

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

public class SymbolEncoder {

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

    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("MAX_VALUE: {}", _alnEncode.encodeFloat(Float.MAX_VALUE));

结果:

MIN_VALUE: 10000000000000000000000000000000
MAX_VALUE: 01111111111111111111111111111111
MIN_VALUE: AAAAAB
MAX_VALUE: 9NUIKX
© www.soinside.com 2019 - 2024. All rights reserved.