Числа Java с основанием › Character.MAX_RADIX

У меня есть строка из пяти символов, и я хочу использовать эти пять символов в качестве числа в кодировке ASCII (для печати). Самый простой способ добиться этого — использовать

Long.toString(number, Character.MAX_RADIX);

Это даст мне числа от "0" до "zzzzz". К сожалению, Long.toString(int, int) поддерживает только строчные буквы, а не заглавные. Это означает, что максимальное основание равно 36, а максимальное число, которое я могу закодировать, равно 36^5 - 1 = 60 466 175. Если бы я мог использовать как строчные , так и прописные буквы, я бы получил максимальное основание счисления 62, а максимальное кодируемое число — 62^5 - 1 = 916 132 831.

Помимо копирования исходного кода Long и расширения возможных цифр, есть ли еще какое-то место, где я должен сначала изучить, где это уже реализовано?


person Lukas Eder    schedule 27.04.2011    source источник
comment
Вы можете поискать кодировщики и декодеры Base64 (например, commons.apache.org/codec/apidocs/org/apache/commons/codec/), которые используют два дополнительных символа для кодирования.   -  person subsub    schedule 27.04.2011
comment
@subsub: см. ответ WhiteFang   -  person Lukas Eder    schedule 27.04.2011


Ответы (2)


Вы не указываете, должны ли символы быть печатными ASCII:

  • Если да, то вы можете пойти в 95^5. Имеется 95 печатных символов ASCII от пробела (SP) до тильды (~).

  • Если нет, то вы можете перейти к 128^5 == 2^35.

В любом случае, алгоритм преобразования прост и проще, чем расширение Long.toString(...). (Вам, по-видимому, не нужно беспокоиться о знаках, ошибках диапазона или пробелах в символьном отображении <-> цифр. Было бы проще закодировать это с нуля.)

Однако мне неизвестно о какой-либо существующей реализации расширенных систем счисления.

person Stephen C    schedule 27.04.2011
comment
Они должны быть пригодны для печати. Я обновлю вопрос, спасибо. Кроме [0-9a-zA-Z] допустимы и некоторые специальные символы (такие как /, -, _ и т.д.) - person Lukas Eder; 27.04.2011
comment
Спасибо за обновления. Я знаю, что это просто. Я могу скопировать его из java.lang.Long. Мне просто интересно, не упустил ли я что-то, где Character.MAX_RADIX не является пределом... - person Lukas Eder; 27.04.2011

Если вы хотите использовать два символа помимо буквенно-цифровых, вы можете использовать кодировку Base64.

Используя Base64 из Apache Commons Codec вы можете получить 1073741824 возможных значения, например:

byte bytes[] = new byte[4];
bytes[0] = (byte) ((value >> 24) & 0xFF);
bytes[1] = (byte) ((value >> 16) & 0xFF);
bytes[2] = (byte) ((value >> 8) & 0xFF);
bytes[3] = (byte) (value & 0xFF);
String encoded = Base64.encodeBase64String(bytes).substring(1, 6);
person WhiteFang34    schedule 27.04.2011
comment
Хорошая идея. Но конечные = и == не будут занимать дополнительное место? Кроме того, я не рассматривал это, потому что трансформация идет из byte[] в String, а не из Number в String. Но я мог справиться с дополнительной кодировкой от Number до byte[] - person Lukas Eder; 27.04.2011
comment
Вы можете избежать завершающего =, используя 3 байта int. Это даст вам четные 24 бита для кодирования в 4 символа. - person WhiteFang34; 27.04.2011
comment
3 байта недостаточно: 256^3 - 1 = 16 777 215, что меньше, чем в моем исходном решении, где я получаю 60 466 175 кодируемых значений - person Lukas Eder; 27.04.2011
comment
Упс, каким-то образом величина вашего числа не была зарегистрирована, и я вслепую превратил для вас 5 символов в 4 :) Я обновил ответ, указав способ получить больше. Для 4 байтов вы можете безопасно обрезать конечный ==. А затем также удалите первый символ, который будет битами из int, которые просто не вписываются в ваши 5 символов. - person WhiteFang34; 27.04.2011
comment
Спасибо за ваши усилия. Это кажется мне более сложным, чем копирование Long.toString(int, int) и добавление пары разрешенных цифр в алгоритм. :-) Кроме того, я недостаточно хорошо понимаю алгоритм base64, чтобы быть уверенным, что обрезка случайно не создаст коллизии, т.е. несколько чисел будут закодированы в одно и то же значение, что в моем случае было бы фатальным. - person Lukas Eder; 27.04.2011