给出一组任意字母
String range = "0123456789abcdefghijklmnopABCD#";
我正在寻找2种方法来编码/解码来自long< - >串
String s = encode( range, l );
和
long l = decode( range, s );
所以decode(range, encode(range, 123456789L)) == 123456789L
如果范围是“0123456789”,这是通常的编码方式。
答案 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