2011-04-27 13 views
12

Tengo una Cadena de cinco caracteres y quiero utilizar esos cinco caracteres como un número codificado en ASCII (imprimible). La forma más sencilla de lograr esto es utilizarNúmeros de Java con raíz> Carácter.MAX_RADIX

Long.toString(number, Character.MAX_RADIX); 

Esto me dará números del "0" a "zzzzz". Desafortunadamente, Long.toString(int, int) solo admite letras minúsculas, no mayúsculas. Esto significa que el límite máximo es 36 y el número más alto que puedo codificar es 36^5 - 1 = 60 466 175. Si pudiera utilizar las letras mayúsculas inferiores y, obtendría una raíz máxima de 62 y el número codificable más alto es 62^5 - 1 = 916 132 831.

Además de copiar el código fuente de Long y ampliar los dígitos posibles, ¿hay algún otro lugar que deba tenerse en cuenta, primero, donde esto ya está implementado?

+0

Es posible que desee buscar codificadores y decodificadores Base64 (por ejemplo, http://commons.apache.org/codec/apidocs/org/apache/commons/codec/binary/Base64.html), que utilizan dos símbolos adicionales para codificar – subsub

+0

@subsub: ver la respuesta de WhiteFang –

Respuesta

3

no especifica si los personajes tienen que ser imprimible ASCII:

  • Si lo hacen, entonces usted puede ir al 95^5. Hay 95 caracteres ASCII imprimibles desde el espacio (SP) hasta la tilde (~).

  • Si no lo hacen, entonces puede ir al 128^5 == 2^35.

De cualquier manera, el algoritmo para hacer la conversión es sencillo, y es más simple que una extensión a Long.toString(...). (Es de suponer que no tiene que preocuparse acerca de los signos, Errores de distancia, o agujeros en el mapeo dígitos carácter <->. Sería más fácil de codificar esto desde el principio.)

Sin embargo, no estoy al tanto de cualquier existente implementación de números extendidos de radix.

+0

Necesitan ser "** imprimibles **". Actualizaré la pregunta, gracias. Además de '[0-9a-zA-Z]', algunos caracteres especiales también estarían bien (como '/', '-',' _', etc.) –

+0

gracias por la actualización. Sé que es sencillo. Puedo copiarlo de 'java.lang.Long'. Me preguntaba si pasé por alto algo donde 'Character.MAX_RADIX' no es el límite ... –

4

Si está dispuesto a usar dos caracteres distintos de los alfanuméricos, puede usar la codificación Base64.

Usando Base64 de Apache Commons Codec usted podría conseguir 1073741824 valores posibles de esta manera:

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); 
+0

Buena idea. Pero el final '=' y '==' no usará espacio extra? Aparte de eso, no lo consideré, porque la transformación va de 'byte []' a 'String', no de' Number' a 'String'. Pero podría manejar la "codificación" adicional de 'Number' a' byte [] ' –

+0

Puede evitar el trailing' = 'usando 3 bytes de un' int'. Eso le daría incluso 24 bits para ser codificados en 4 caracteres. – WhiteFang34

+0

3 bytes no es suficiente: '256^3 - 1 = 16 777 215', que es menor que mi solución original donde obtengo' 60 466 175' valores codificables –