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

#java #tostring #radix

#java #tostring #основание

Вопрос:

У меня есть строка из пяти символов, и я хочу использовать эти пять символов в качестве числа в кодировке 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 исходного кода и расширения возможных цифр, есть ли какое-либо другое место, в которое я должен сначала заглянуть, где это уже реализовано?

Комментарии:

1. Возможно, вам захочется поискать кодировщики и декодеры Base64 (например, commons.apache.org/codec/apidocs/org/apache/commons/codec /… ), которые используют два дополнительных символа для кодирования.

2. @subsub: смотрите ответ WhiteFang

Ответ №1:

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

Используя Base64 из кодека Apache Commons, вы могли бы получить 1073741824 возможных значения, подобные этому:

 byte bytes[] = new byte[4];
bytes[0] = (byte) ((value >> 24) amp; 0xFF);
bytes[1] = (byte) ((value >> 16) amp; 0xFF);
bytes[2] = (byte) ((value >> 8) amp; 0xFF);
bytes[3] = (byte) (value amp; 0xFF);
String encoded = Base64.encodeBase64String(bytes).substring(1, 6);
  

Комментарии:

1. Хорошая идея. Но завершающие = и == не будут занимать дополнительное пространство? Кроме этого, я это не рассматривал, потому что преобразование выполняется из byte[] в String , а не из Number в String . Но я мог бы обработать дополнительную «кодировку» от Number до byte[]

2. Вы могли бы избежать завершения, = используя 3 байта из int . Это дало бы вам ровно 24 бита для кодирования в 4 символа.

3. недостаточно 3 байт: 256^3 - 1 = 16 777 215 , что меньше, чем в моем оригинальном решении, где я получаю 60 466 175 кодируемые значения

4. Упс, каким-то образом величина вашего числа не была зарегистрирована, и я слепо превратил 5 символов в 4 для вас 🙂 Я обновил ответ, добавив способ получить больше. На 4 байта вы можете безопасно обрезать конечную строку == . А затем также удалите первый символ, который будет битами из int , которые просто не поместятся в ваши 5 символов.

5. Спасибо за ваши усилия. Для меня это звучит сложнее, чем копирование Long.toString(int, int) и добавление пары разрешенных цифр в алгоритм. 🙂 Кроме того, я недостаточно хорошо понимаю алгоритм base64, чтобы быть уверенным, что обрезка случайно не приведет к «коллизиям», т. Е. нескольким числам, закодированным в одно и то же значение, что в моем случае было бы фатальным.

Ответ №2:

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

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

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

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

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

Комментарии:

1. Они должны быть «для печати «. Я обновлю вопрос, спасибо. Кроме [0-9a-zA-Z] некоторых специальных символов, тоже было бы неплохо (таких как / , - _ и т.д.)

2. спасибо за обновление. Я знаю, что это просто. Я могу скопировать его из java.lang.Long . Мне просто интересно, не упустил ли я что-то, что Character.MAX_RADIX не является пределом…

3. @LukasEder ICU — это место, где вы ожидаете существования реализации. В настоящее время заявка находится в статусе accepted, так что сейчас самое время ввести требования.