una - generar password aleatorio en java




¿Cómo generar una cadena alfanumérica aleatoria? (20)

Algoritmo

Para generar una cadena aleatoria, concatene caracteres dibujados aleatoriamente del conjunto de símbolos aceptables hasta que la cadena alcance la longitud deseada.

Implementación

Aquí hay un código bastante simple y muy flexible para generar identificadores aleatorios. Lea la información que sigue para las notas importantes de la aplicación.

import java.security.SecureRandom;
import java.util.Locale;
import java.util.Objects;
import java.util.Random;

public class RandomString {

    /**
     * Generate a random string.
     */
    public String nextString() {
        for (int idx = 0; idx < buf.length; ++idx)
            buf[idx] = symbols[random.nextInt(symbols.length)];
        return new String(buf);
    }

    public static final String upper = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";

    public static final String lower = upper.toLowerCase(Locale.ROOT);

    public static final String digits = "0123456789";

    public static final String alphanum = upper + lower + digits;

    private final Random random;

    private final char[] symbols;

    private final char[] buf;

    public RandomString(int length, Random random, String symbols) {
        if (length < 1) throw new IllegalArgumentException();
        if (symbols.length() < 2) throw new IllegalArgumentException();
        this.random = Objects.requireNonNull(random);
        this.symbols = symbols.toCharArray();
        this.buf = new char[length];
    }

    /**
     * Create an alphanumeric string generator.
     */
    public RandomString(int length, Random random) {
        this(length, random, alphanum);
    }

    /**
     * Create an alphanumeric strings from a secure generator.
     */
    public RandomString(int length) {
        this(length, new SecureRandom());
    }

    /**
     * Create session identifiers.
     */
    public RandomString() {
        this(21);
    }

}

Ejemplos de uso

Cree un generador inseguro para identificadores de 8 caracteres:

RandomString gen = new RandomString(8, ThreadLocalRandom.current());

Cree un generador seguro para identificadores de sesión:

RandomString session = new RandomString();

Cree un generador con códigos de fácil lectura para imprimir. Las cadenas son más largas que las cadenas alfanuméricas completas para compensar el uso de menos símbolos:

String easy = RandomString.digits + "ACEFGHJKLMNPQRUVWXYabcdefhijkprstuvwx";
RandomString tickets = new RandomString(23, new SecureRandom(), easy);

Utilizar como identificadores de sesión

Generar identificadores de sesión que probablemente sean únicos no es lo suficientemente bueno, o simplemente puede usar un contador simple. Los atacantes secuestran sesiones cuando se usan identificadores predecibles.

Hay tensión entre la longitud y la seguridad. Los identificadores más cortos son más fáciles de adivinar, porque hay menos posibilidades. Pero los identificadores más largos consumen más almacenamiento y ancho de banda. Un conjunto mayor de símbolos ayuda, pero puede causar problemas de codificación si los identificadores se incluyen en las URL o se ingresan manualmente.

La fuente subyacente de aleatoriedad, o entropía, para los identificadores de sesión debe provenir de un generador de números aleatorios diseñado para la criptografía. Sin embargo, la inicialización de estos generadores a veces puede ser computacionalmente costosa o lenta, por lo que se debe hacer un esfuerzo para reutilizarlos cuando sea posible.

Utilizar como identificadores de objetos.

No todas las aplicaciones requieren seguridad. La asignación aleatoria puede ser una forma eficiente para que múltiples entidades generen identificadores en un espacio compartido sin ninguna coordinación o partición. La coordinación puede ser lenta, especialmente en un entorno agrupado o distribuido, y dividir un espacio causa problemas cuando las entidades terminan con recursos compartidos que son demasiado pequeños o demasiado grandes.

Los identificadores generados sin tomar medidas para hacerlos impredecibles deben protegerse por otros medios si un atacante puede verlos y manipularlos, como ocurre en la mayoría de las aplicaciones web. Debe haber un sistema de autorización separado que proteja los objetos cuyo identificador pueda ser adivinado por un atacante sin permiso de acceso.

También se debe tener cuidado al usar identificadores que sean lo suficientemente largos para hacer que las colisiones sean poco probables dado el número total de identificadores previsto. Esto se conoce como "la paradoja del cumpleaños". La probabilidad de una colisión, p , es aproximadamente n 2 / (2q x ), donde n es el número de identificadores realmente generados, q es el número de símbolos distintos en el alfabeto yx es la longitud de los identificadores. Este debe ser un número muy pequeño, como 2 ‑50 o menos.

Resolver esto muestra que la posibilidad de colisión entre 500k identificadores de 15 caracteres es de aproximadamente 2 a 52 , lo cual es probablemente menos probable que los errores no detectados de los rayos cósmicos, etc.

Comparación con los UUIDs

Según su especificación, los UUID no están diseñados para ser impredecibles y no deben utilizarse como identificadores de sesión.

Los UUID en su formato estándar ocupan mucho espacio: 36 caracteres para solo 122 bits de entropía. (No todos los bits de un UUID "aleatorio" se seleccionan al azar.) Una cadena alfanumérica elegida al azar contiene más entropía en solo 21 caracteres.

Los UUID no son flexibles; Tienen una estructura y distribución estandarizadas. Esta es su principal virtud, así como su principal debilidad. Cuando se colabora con un tercero, la estandarización ofrecida por los UUID puede ser útil. Para uso puramente interno, pueden ser ineficientes.

He estado buscando un algoritmo Java simple para generar una cadena alfa-numérica pseudoaleatoria. En mi situación, se usaría como un único identificador de sesión / clave que "probablemente" sería único en una generación de más de 500 K (mis necesidades no requieren nada mucho más sofisticado). Idealmente, podría especificar una longitud según mis necesidades únicas. Por ejemplo, una cadena de longitud 12 generada podría parecerse a "AEYGF7K0DM1X" .


  1. Cambie los caracteres de la secuencia según sus requisitos.

  2. La cuerda es inmutable. Aquí StringBuilder.append es más eficiente que la concatenación de cadenas.


public static String getRandomString(int length) {
       final String characters = "[email protected]#$%^&*()_+";
       StringBuilder result = new StringBuilder();
       while(length > 0) {
           Random rand = new Random();
           result.append(characters.charAt(rand.nextInt(characters.length())));
           length--;
       }
       return result.toString();
    }

El uso de UUID es inseguro, porque las partes de UUID no son aleatorias en absoluto. El procedimiento de @erickson es muy claro, pero no crea cadenas de la misma longitud. El siguiente fragmento debería ser suficiente:

/*
 * The random generator used by this class to create random keys.
 * In a holder class to defer initialization until needed.
 */
private static class RandomHolder {
    static final Random random = new SecureRandom();
    public static String randomKey(int length) {
        return String.format("%"+length+"s", new BigInteger(length*5/*base 32,2^5*/, random)
            .toString(32)).replace('\u0020', '0');
    }
}

Por qué elegir la length*5 . Asumamos el caso simple de una cadena aleatoria de longitud 1, por lo que un carácter aleatorio. Para obtener un carácter aleatorio que contenga todos los dígitos 0-9 y caracteres az, necesitaríamos un número aleatorio entre 0 y 35 para obtener uno de cada carácter. BigInteger proporciona un constructor para generar un número aleatorio, distribuido uniformemente en el rango de 0 to (2^numBits - 1) . Desafortunadamente, 35 no es un número que pueda ser recibido por 2 ^ numBits - 1. Así que tenemos dos opciones: O ir con 2^5-1=31 o 2^6-1=63 . Si escogiéramos 2^6 obtendríamos muchos números "innecesarios" / "más largos". Por lo tanto, 2^5 es la mejor opción, incluso si perdemos 4 caracteres (wz). Para generar ahora una cadena de cierta longitud, simplemente podemos usar un número de 2^(length*numBits)-1 . El último problema, si queremos una cadena con una cierta longitud, el azar podría generar un número pequeño, por lo que la longitud no se cumple, por lo que tenemos que rellenar la cadena a la longitud requerida, antes de ceros.



Esto es fácilmente alcanzable sin ninguna biblioteca externa.

1. Generación criptográfica de datos pseudoaleatorios.

Primero necesitas un PRNG criptográfico. Java tiene SecureRandom para el que normalmente utiliza la mejor fuente de entropía en la máquina (por ejemplo, /dev/random ). Leer más aquí.

SecureRandom rnd = new SecureRandom();
byte[] token = new byte[byteLength];
rnd.nextBytes(token);

Nota: SecureRandom es la forma más lenta, pero más segura en Java de generar bytes aleatorios. Sin embargo, recomiendo NO considerar el rendimiento aquí, ya que generalmente no tiene un impacto real en su aplicación a menos que tenga que generar millones de tokens por segundo.

2. Espacio requerido de valores posibles

A continuación, debe decidir "qué tan único" debe ser su token. El único y único punto de considerar la entropía es asegurarse de que el sistema pueda resistir los ataques de fuerza bruta: el espacio de los posibles valores debe ser tan grande que cualquier atacante solo pueda probar una proporción insignificante de los valores en un tiempo no ridículo 1 . Los identificadores únicos, como el UUID aleatorio, tienen 122 bits de entropía (es decir, 2 ^ 122 = 5.3x10 ^ 36): la posibilidad de colisión es "* (...) porque existe una probabilidad entre mil millones de duplicados, 103 billones Los UUID de la versión 4 se deben generar 2 ". Elegiremos 128 bits, ya que encaja exactamente en 16 bytes y se considera que es lo suficientemente alto para ser único en prácticamente todos los casos de uso, pero los más extremos, y no tiene que pensar en duplicados. Aquí hay una tabla de comparación simple de entropía que incluye un análisis simple del problema del cumpleaños .

Para requisitos simples, la longitud de 8 o 12 bytes puede ser suficiente, pero con 16 bytes se encuentra en el "lado seguro".

Y eso es básicamente eso. Lo último es pensar en la codificación para que se pueda representar como un texto imprimible (leído, una String ).

3. Codificación de binario a texto

Las codificaciones típicas incluyen:

  • Base64 cada carácter codifica 6bit creando una sobrecarga del 33%. Desafortunadamente, no hay una implementación estándar en el JDK ( 7 y más adelante ; existe en Android y Java 8+ ). Pero existen numerosas bibliotecas que agregan esto. El inconveniente es que la Base64 estándar no es segura para, por ejemplo. urls y como nombre de archivo en la mayoría de los sistemas de archivos que requieren codificación adicional (por ejemplo, codificación url ) o se usa la versión segura de URL de Base64 . Ejemplo de codificación de 16 bytes con relleno: XfJhfv3C0P6ag7y9VQxSbw==

  • Base32 cada carácter codifica 5bit creando una sobrecarga del 40%. Esto utilizará AZ y 2-7 lo que hace que sea razonablemente eficiente en cuanto al espacio y que sea alfanumérico sin distinción de mayúsculas. No hay implementación estándar en el JDK . Ejemplo de codificación de 16 bytes sin relleno: WUPIL5DQTZGMF4D3NX5L7LNFOY

  • Base16 (hexadecimal) cada carácter codifica 4 bits que requieren 2 caracteres por byte (es decir, 16 bytes crean una cadena de longitud 32). Por lo tanto, el hex es menos eficiente en espacio que Base32 pero es seguro de usar en la mayoría de los casos (url) ya que solo usa 0-9 y A a F Ejemplo de codificación de 16 bytes: 4fa3dd0f57cb3bf331441ed285b27735 . Vea una discusión SO sobre la conversión a hexadecimal aquí.

Existen codificaciones adicionales como Base85 y la exótica Base122 con una eficiencia de espacio mejor / peor. Puede crear su propia codificación (que básicamente lo hacen la mayoría de las respuestas en este hilo) pero no lo recomendaría si no tiene requisitos muy específicos. Ver más esquemas de codificación en el artículo de Wikipedia.

4. Resumen y ejemplo

  • Utilice SecureRandom
  • Utilice al menos 16 bytes (2 ^ 128) de valores posibles
  • Codifique de acuerdo con sus requisitos (generalmente hex o base32 si necesita que sea alfanumérico)

No hacer

  • ... use la codificación de su cerveza casera: mejor mantenible y legible para otros si ven qué codificación estándar utiliza en lugar de extraño para los bucles que crean caracteres a la vez.
  • ... use UUID: está desperdiciando 6 bits de entropía y tiene una representación de cadena detallada

Ejemplo: Hex Token Generator

public static String generateRandomHexToken(int byteLength) {
    SecureRandom secureRandom = new SecureRandom();
    byte[] token = new byte[byteLength];
    secureRandom.nextBytes(token);
    return new BigInteger(1, token).toString(16); //hex encoding
}

//generateRandomHexToken(16) -> 2189df7475e96aa3982dbeab266497cd

Ejemplo: Herramienta

Si desea una herramienta cli lista para usar, puede usar los dados: https://github.com/patrickfav/dice


Java proporciona una forma de hacerlo directamente. Si no quieres los guiones, son fáciles de quitar. Solo usa uuid.replace("-", "")

import java.util.UUID;

public class randomStringGenerator {
    public static void main(String[] args) {
        System.out.println(generateString());
    }

    public static String generateString() {
        String uuid = UUID.randomUUID().toString();
        return "uuid = " + uuid;
    }
}

Salida:

uuid = 2d7428a6-b58c-4008-8575-f05549f16316

Si está contento de usar las clases de Apache, puede usar org.apache.commons.text.RandomStringGenerator (commons-text).

Ejemplo:

RandomStringGenerator randomStringGenerator =
        new RandomStringGenerator.Builder()
                .withinRange('0', 'z')
                .filteredBy(CharacterPredicates.LETTERS, CharacterPredicates.DIGITS)
                .build();
randomStringGenerator.generate(12); // toUpperCase() if you want

Desde commons-lang 3.6, RandomStringUtils está en desuso.


Sorprendente nadie aquí lo ha sugerido pero:

import java.util.UUID

UUID.randomUUID().toString();

Fácil.

La ventaja de esto es que los UUID son agradables y largos y se garantiza que son casi imposibles de colisionar.

Wikipedia tiene una buena explicación de ello:

"... solo después de generar 1 mil millones de UUID por segundo durante los próximos 100 años, la probabilidad de crear un solo duplicado sería de alrededor del 50%".

http://en.wikipedia.org/wiki/Universally_unique_identifier#Random_UUID_probability_of_duplicates

Los primeros 4 bits son el tipo de versión y 2 para la variante, por lo que obtienes 122 bits de forma aleatoria. Entonces, si lo desea , puede truncar desde el final para reducir el tamaño del UUID. No se recomienda, pero aún tienes mucha aleatoriedad, suficiente para que tus registros de 500k sean fáciles.


Una solución corta y fácil, pero solo usa letras minúsculas y números:

Random r = new java.util.Random ();
String s = Long.toString (r.nextLong () & Long.MAX_VALUE, 36);

El tamaño es de aproximadamente 12 dígitos a la base 36 y no se puede mejorar más de esa manera. Por supuesto puedes adjuntar múltiples instancias.


Usando Dollar debería ser simple como:

// "0123456789" + "ABCDE...Z"
String validCharacters = $('0', '9').join() + $('A', 'Z').join();

String randomString(int length) {
    return $(validCharacters).shuffle().slice(length).toString();
}

@Test
public void buildFiveRandomStrings() {
    for (int i : $(5)) {
        System.out.println(randomString(12));
    }
}

produce algo así:

DKL1SBH9UJWC
JH7P0IT21EA5
5DTI72EO6SFU
HQUMJTEBNF7Y
1HCR6SKYWGT7

Mejor método de generador de cadenas aleatorias

public class RandomStringGenerator{

    private static int randomStringLength = 25 ;
    private static boolean allowSpecialCharacters = true ;
    private static String specialCharacters = "[email protected]$%*-_+:";
    private static boolean allowDuplicates = false ;

    private static boolean isAlphanum = false;
    private static boolean isNumeric = false;
    private static boolean isAlpha = false;
    private static final String alphabet = "abcdefghijklmnopqrstuvwxyz";
    private static boolean mixCase = false;
    private static final String capAlpha = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
    private static final String num = "0123456789";

    public static String getRandomString() {
        String returnVal = "";
        int specialCharactersCount = 0;
        int maxspecialCharacters = randomStringLength/4;

        try {
            StringBuffer values = buildList();
            for (int inx = 0; inx < randomStringLength; inx++) {
                int selChar = (int) (Math.random() * (values.length() - 1));
                if (allowSpecialCharacters)
                {
                    if (specialCharacters.indexOf("" + values.charAt(selChar)) > -1)
                    {
                        specialCharactersCount ++;
                        if (specialCharactersCount > maxspecialCharacters)
                        {
                            while (specialCharacters.indexOf("" + values.charAt(selChar)) != -1)
                            {
                                selChar = (int) (Math.random() * (values.length() - 1));
                            }
                        }
                    }
                }
                returnVal += values.charAt(selChar);
                if (!allowDuplicates) {
                    values.deleteCharAt(selChar);
                }
            }
        } catch (Exception e) {
            returnVal = "Error While Processing Values";
        }
        return returnVal;
    }

    private static StringBuffer buildList() {
        StringBuffer list = new StringBuffer(0);
        if (isNumeric || isAlphanum) {
            list.append(num);
        }
        if (isAlpha || isAlphanum) {
            list.append(alphabet);
            if (mixCase) {
                list.append(capAlpha);
            }
        }
        if (allowSpecialCharacters)
        {
            list.append(specialCharacters);
        }
        int currLen = list.length();
        String returnVal = "";
        for (int inx = 0; inx < currLen; inx++) {
            int selChar = (int) (Math.random() * (list.length() - 1));
            returnVal += list.charAt(selChar);
            list.deleteCharAt(selChar);
        }
        list = new StringBuffer(returnVal);
        return list;
    }   

}

Puede usar el siguiente código, si su contraseña obligatoria contiene números caracteres alfabéticos especiales:

private static final String NUMBERS = "0123456789";
private static final String UPPER_ALPHABETS = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
private static final String LOWER_ALPHABETS = "abcdefghijklmnopqrstuvwxyz";
private static final String SPECIALCHARACTERS = "@#$%&*";
private static final int MINLENGTHOFPASSWORD = 8;

public static String getRandomPassword() {
    StringBuilder password = new StringBuilder();
    int j = 0;
    for (int i = 0; i < MINLENGTHOFPASSWORD; i++) {
        password.append(getRandomPasswordCharacters(j));
        j++;
        if (j == 3) {
            j = 0;
        }
    }
    return password.toString();
}

private static String getRandomPasswordCharacters(int pos) {
    Random randomNum = new Random();
    StringBuilder randomChar = new StringBuilder();
    switch (pos) {
        case 0:
            randomChar.append(NUMBERS.charAt(randomNum.nextInt(NUMBERS.length() - 1)));
            break;
        case 1:
            randomChar.append(UPPER_ALPHABETS.charAt(randomNum.nextInt(UPPER_ALPHABETS.length() - 1)));
            break;
        case 2:
            randomChar.append(SPECIALCHARACTERS.charAt(randomNum.nextInt(SPECIALCHARACTERS.length() - 1)));
            break;
        case 3:
            randomChar.append(LOWER_ALPHABETS.charAt(randomNum.nextInt(LOWER_ALPHABETS.length() - 1)));
            break;
    }
    return randomChar.toString();

}

Realmente no me gusta ninguna de estas respuestas con respecto a la solución "simple": S

Iría por un simple;), java puro, un trazador de líneas (la entropía se basa en la longitud de cadena aleatoria y el conjunto de caracteres dado):

public String randomString(int length, String characterSet) {
    return IntStream.range(0, length).map(i -> new SecureRandom().nextInt(characterSet.length())).mapToObj(randomInt -> characterSet.substring(randomInt, randomInt + 1)).collect(Collectors.joining());
}

@Test
public void buildFiveRandomStrings() {
    for (int q = 0; q < 5; q++) {
        System.out.println(randomString(10, "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"));//charachterSet can basically be anything
    }
}

o (un poco más legible forma antigua)

public String randomString(int length, String characterSet) {
    StringBuilder sb = new StringBuilder(); //consider using StringBuffer if needed
    for (int i = 0; i < length; i++) {
        int randomInt = new SecureRandom().nextInt(characterSet.length());
        sb.append(characterSet.substring(randomInt, randomInt + 1));
    }
    return sb.toString();
}

@Test
public void buildFiveRandomStrings() {
    for (int q = 0; q < 5; q++) {
        System.out.println(randomString(10, "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789")); //charachterSet can basically be anything
    }
}

Pero, por otro lado, también podrías usar UUID, que tiene una entropía bastante buena ( 2 ):

UUID.randomUUID().toString().replace("-", "")

Espero que ayude.


Tal vez esto sea útil

package password.generater;

import java.util.Random;

/**
 *
 * @author dell
 */
public class PasswordGenerater {

    /**
     * @param args the command line arguments
     */
    public static void main(String[] args) {
        int length= 11;
        System.out.println(generatePswd(length));

        // TODO code application logic here
    }
    static char[] generatePswd(int len){
        System.out.println("Your Password ");
        String charsCaps="ABCDEFGHIJKLMNOPQRSTUVWXYZ"; 
        String Chars="abcdefghijklmnopqrstuvwxyz";
        String nums="0123456789";
        String symbols="[email protected]#$%^&*()_+-=.,/';:?><~*/-+";
        String passSymbols=charsCaps + Chars + nums +symbols;
        Random rnd=new Random();
        char[] password=new char[len];

        for(int i=0; i<len;i++){
            password[i]=passSymbols.charAt(rnd.nextInt(passSymbols.length()));
        }
      return password;

    }
}

Aquí está el código de una línea por AbacusUtil

String.valueOf(CharStream.random('0', 'z').filter(c -> N.isLetterOrDigit(c)).limit(12).toArray())

Aleatorio no significa que debe ser único. para obtener cadenas únicas, utilizando:

N.uuid() // e.g.: "e812e749-cf4c-4959-8ee1-57829a69a80f". length is 36.
N.guid() // e.g.: "0678ce04e18945559ba82ddeccaabfcd". length is 32 without '-'

Menciona "simple", pero en caso de que alguien más esté buscando algo que cumpla con los requisitos de seguridad más estrictos, es posible que desee ver jpwgen . jpwgen está modelado después de pwgen en Unix, y es muy configurable.


import java.util.Date;
import java.util.Random;

public class RandomGenerator {

  private static Random random = new Random((new Date()).getTime());

    public static String generateRandomString(int length) {
      char[] values = {'a','b','c','d','e','f','g','h','i','j',
               'k','l','m','n','o','p','q','r','s','t',
               'u','v','w','x','y','z','0','1','2','3',
               '4','5','6','7','8','9'};

      String out = "";

      for (int i=0;i<length;i++) {
          int idx=random.nextInt(values.length);
          out += values[idx];
      }
      return out;
    }
}

import java.util.Random;

public class passGen{
    //Verison 1.0
    private static final String dCase = "abcdefghijklmnopqrstuvwxyz";
    private static final String uCase = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
    private static final String sChar = "[email protected]#$%^&*";
    private static final String intChar = "0123456789";
    private static Random r = new Random();
    private static String pass = "";

    public static void main (String[] args) {
        System.out.println ("Generating pass...");
        while (pass.length () != 16){
            int rPick = r.nextInt(4);
            if (rPick == 0){
                int spot = r.nextInt(25);
                pass += dCase.charAt(spot);
            } else if (rPick == 1) {
                int spot = r.nextInt (25);
                pass += uCase.charAt(spot);
            } else if (rPick == 2) {
                int spot = r.nextInt (7);
                pass += sChar.charAt(spot);
            } else if (rPick == 3){
                int spot = r.nextInt (9);
                pass += intChar.charAt (spot);
            }
        }
        System.out.println ("Generated Pass: " + pass);
    }
}

Entonces, lo que esto hace es simplemente agregar la contraseña a la cadena y ... sí, funciona bien, échale un vistazo ... muy simple. yo lo escribi


public static String getRandomString(int length) {
        char[] chars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRST".toCharArray();

        StringBuilder sb = new StringBuilder();
        Random random = new Random();
        for (int i = 0; i < chars.length; i++) {
            char c = chars[random.nextInt(chars.length)];
            sb.append(c);
        }
        String randomStr = sb.toString();

        return randomStr;
    }

public static String randomSeriesForThreeCharacter() {
    Random r = new Random();
    String value="";
    char random_Char ;
    for(int i=0; i<10;i++)
    { 
        random_Char = (char) (48 + r.nextInt(74));
        value=value+random_char;
    }
    return value;
}




alphanumeric