Cambiarle las etiquetas <js> y </js> por las correspondientes para añadir el javascript al html. Lo puse así para que el Cloudfare no me detecte los scripts y no me rediriga en bucle a captchas al publicar el código en el foro.
Podeis probarlo offline con un copia y pega, substituyendo las etiquetas y guardándolo con extensión html o htm con el bloc de notas o cualquier otro editor de texto dándole a "guardar como". Por ejemplo: cifradobase64.html
Podeis añadirlo a vuestra web o usarlo como querais y para lo que querais.
Características.
-La implementación es super sencilla de entender. Así quien no sepa como funciona exactamente el cifrado base64, buscándolo en wikipedia (o en el propio foro de criptografía se lo expliqué a un usuario) y mirando el código pueda entenderlo. A parte es fácilmente portable a cualquier otro lenguaje.
-Filtra todos los espacios y carácteres no contemplados en la tabla común del cifrado base64 del texto original. Se le añaden fácilmente si se desea.
-Facil cambiar la base de 64 a otra base.
-Solo cifra, no descifra. Le añadí el igual al texto cifrado (en caso de necesitarlo) para poder descifrarlo con cualquier herramienta online o implementar vosotros el decoder. Puede que lo haga yo y lo suba también cuando me aburra.
Código
<html> <head><title>Encoder Base64</title></head> <body> <js> var CadenaEnTexto; var CadenaEnTextoTamanho; var CadenaEnASCII = ""; var CadenaDeBits6en6 = ""; var CadenaDeBits6en6Tamanho; var RestoDeDividirEntre6 = 0; var ContadorNumDeCerosAnhadidos = 0; var mantenerseEnBucle = true; var TempBits6 = ""; var x = 0; var z = 0; var CifradoFinal = ""; CadenaEnTexto = prompt("Pon el texto"); CadenaEnTextoTamanho = CadenaEnTexto.length; for (var i = 0; i < CadenaEnTextoTamanho; ++i) { if (CadenaEnTexto[i] == 'A') { CadenaEnASCII += "01000001"; } if (CadenaEnTexto[i] == 'B') { CadenaEnASCII += "01000010"; } if (CadenaEnTexto[i] == 'C') { CadenaEnASCII += "01000011"; } if (CadenaEnTexto[i] == 'D') { CadenaEnASCII += "01000100"; } if (CadenaEnTexto[i] == 'E') { CadenaEnASCII += "01000101"; } if (CadenaEnTexto[i] == 'F') { CadenaEnASCII += "01000110"; } if (CadenaEnTexto[i] == 'G') { CadenaEnASCII += "01000111"; } if (CadenaEnTexto[i] == 'H') { CadenaEnASCII += "01001000"; } if (CadenaEnTexto[i] == 'I') { CadenaEnASCII += "01001001"; } if (CadenaEnTexto[i] == 'J') { CadenaEnASCII += "01001010"; } if (CadenaEnTexto[i] == 'K') { CadenaEnASCII += "01001011"; } if (CadenaEnTexto[i] == 'L') { CadenaEnASCII += "01001100"; } if (CadenaEnTexto[i] == 'M') { CadenaEnASCII += "01001101"; } if (CadenaEnTexto[i] == 'N') { CadenaEnASCII += "01001110"; } if (CadenaEnTexto[i] == 'O') { CadenaEnASCII += "01001111"; } if (CadenaEnTexto[i] == 'P') { CadenaEnASCII += "01010000"; } if (CadenaEnTexto[i] == 'Q') { CadenaEnASCII += "01010001"; } if (CadenaEnTexto[i] == 'R') { CadenaEnASCII += "01010010"; } if (CadenaEnTexto[i] == 'S') { CadenaEnASCII += "01010011"; } if (CadenaEnTexto[i] == 'T') { CadenaEnASCII += "01010100"; } if (CadenaEnTexto[i] == 'U') { CadenaEnASCII += "01010101"; } if (CadenaEnTexto[i] == 'V') { CadenaEnASCII += "01010110"; } if (CadenaEnTexto[i] == 'W') { CadenaEnASCII += "01010111"; } if (CadenaEnTexto[i] == 'X') { CadenaEnASCII += "01011000"; } if (CadenaEnTexto[i] == 'Y') { CadenaEnASCII += "01011001"; } if (CadenaEnTexto[i] == 'Z') { CadenaEnASCII += "01011010"; } if (CadenaEnTexto[i] == 'a') { CadenaEnASCII += "01100001" ; } if (CadenaEnTexto[i] == 'b') { CadenaEnASCII += "01100010"; } if (CadenaEnTexto[i] == 'c') { CadenaEnASCII += "01100011"; } if (CadenaEnTexto[i] == 'd') { CadenaEnASCII += "01100100"; } if (CadenaEnTexto[i] == 'e') { CadenaEnASCII += "01100101"; } if (CadenaEnTexto[i] == 'f') { CadenaEnASCII += "01100110"; } if (CadenaEnTexto[i] == 'g') { CadenaEnASCII += "01100111"; } if (CadenaEnTexto[i] == 'h') { CadenaEnASCII += "01101000"; } if (CadenaEnTexto[i] == 'i') { CadenaEnASCII += "01101001"; } if (CadenaEnTexto[i] == 'j') { CadenaEnASCII += "01101010"; } if (CadenaEnTexto[i] == 'k') { CadenaEnASCII += "01101011"; } if (CadenaEnTexto[i] == 'l') { CadenaEnASCII += "01101100"; } if (CadenaEnTexto[i] == 'm') { CadenaEnASCII += "01101101"; } if (CadenaEnTexto[i] == 'n') { CadenaEnASCII += "01101110"; } if (CadenaEnTexto[i] == 'o') { CadenaEnASCII += "01101111"; } if (CadenaEnTexto[i] == 'p') { CadenaEnASCII += "01110000"; } if (CadenaEnTexto[i] == 'q') { CadenaEnASCII += "01110001"; } if (CadenaEnTexto[i] == 'r') { CadenaEnASCII += "01110010"; } if (CadenaEnTexto[i] == 's') { CadenaEnASCII += "01110011"; } if (CadenaEnTexto[i] == 't') { CadenaEnASCII += "01110100"; } if (CadenaEnTexto[i] == 'u') { CadenaEnASCII += "01110101"; } if (CadenaEnTexto[i] == 'v') { CadenaEnASCII += "01110110"; } if (CadenaEnTexto[i] == 'w') { CadenaEnASCII += "01110111"; } if (CadenaEnTexto[i] == 'x') { CadenaEnASCII += "01111000"; } if (CadenaEnTexto[i] == 'y') { CadenaEnASCII += "01111001"; } if (CadenaEnTexto[i] == 'z') { CadenaEnASCII += "01111010"; } if (CadenaEnTexto[i] == '0') { CadenaEnASCII += "00110000"; } if (CadenaEnTexto[i] == '1') { CadenaEnASCII += "00110001"; } if (CadenaEnTexto[i] == '2') { CadenaEnASCII += "00110010"; } if (CadenaEnTexto[i] == '3') { CadenaEnASCII += "00110011"; } if (CadenaEnTexto[i] == '4') { CadenaEnASCII += "00110100"; } if (CadenaEnTexto[i] == '5') { CadenaEnASCII += "00110101"; } if (CadenaEnTexto[i] == '6') { CadenaEnASCII += "00110110"; } if (CadenaEnTexto[i] == '7') { CadenaEnASCII += "00110111"; } if (CadenaEnTexto[i] == '8') { CadenaEnASCII += "00111000"; } if (CadenaEnTexto[i] == '9') { CadenaEnASCII += "00111001"; } if (CadenaEnTexto[i] == '+') { CadenaEnASCII += "00101011"; } if (CadenaEnTexto[i] == '/') { CadenaEnASCII += "00101111"; } } CadenaDeBits6en6 += CadenaEnASCII; CadenaDeBits6en6Tamanho = CadenaDeBits6en6.length; RestoDeDividirEntre6 = CadenaDeBits6en6Tamanho % 6; switch (RestoDeDividirEntre6) { case 2: { CadenaDeBits6en6 += "0000"; ContadorNumDeCerosAnhadidos = 4; CadenaDeBits6en6Tamanho += 4; } break; case 4: { CadenaDeBits6en6 += "00"; ContadorNumDeCerosAnhadidos = 2; CadenaDeBits6en6Tamanho += 2; } break; default: { } break; } do { TempBits6 += CadenaDeBits6en6[z]; x++; z++; if (x == 6 ) { if ( TempBits6 == "000000") { CifradoFinal += "A"; } if ( TempBits6 == "000001") { CifradoFinal += "B"; } if ( TempBits6 == "000010") { CifradoFinal += "C"; } if ( TempBits6 == "000011") { CifradoFinal += "D"; } if ( TempBits6 == "000100") { CifradoFinal += "E"; } if ( TempBits6 == "000101") { CifradoFinal += "F"; } if ( TempBits6 == "000110") { CifradoFinal += "G"; } if ( TempBits6 == "000111") { CifradoFinal += "H"; } if ( TempBits6 == "001000") { CifradoFinal += "I"; } if ( TempBits6 == "001001") { CifradoFinal += "J"; } if ( TempBits6 == "001010") { CifradoFinal += "K"; } if ( TempBits6 == "001011") { CifradoFinal += "L"; } if ( TempBits6 == "001100") { CifradoFinal += "M"; } if ( TempBits6 == "001101") { CifradoFinal += "N"; } if ( TempBits6 == "001110") { CifradoFinal += "O"; } if ( TempBits6 == "001111") { CifradoFinal += "P"; } if ( TempBits6 == "010000") { CifradoFinal += "Q"; } if ( TempBits6 == "010001") { CifradoFinal += "R"; } if ( TempBits6 == "010010") { CifradoFinal += "S"; } if ( TempBits6 == "010011") { CifradoFinal += "T"; } if ( TempBits6 == "010100") { CifradoFinal += "U"; } if ( TempBits6 == "010101") { CifradoFinal += "V"; } if ( TempBits6 == "010110") { CifradoFinal += "W"; } if ( TempBits6 == "010111") { CifradoFinal += "X"; } if ( TempBits6 == "011000") { CifradoFinal += "Y"; } if ( TempBits6 == "011001") { CifradoFinal += "Z"; } if ( TempBits6 == "011010") { CifradoFinal += "a"; } if ( TempBits6 == "011011") { CifradoFinal += "b"; } if ( TempBits6 == "011100") { CifradoFinal += "c"; } if ( TempBits6 == "011101") { CifradoFinal += "d"; } if ( TempBits6 == "011110") { CifradoFinal += "e"; } if ( TempBits6 == "011111") { CifradoFinal += "f"; } if ( TempBits6 == "100000") { CifradoFinal += "g"; } if ( TempBits6 == "100001") { CifradoFinal += "h"; } if ( TempBits6 == "100010") { CifradoFinal += "i"; } if ( TempBits6 == "100011") { CifradoFinal += "j"; } if ( TempBits6 == "100100") { CifradoFinal += "k"; } if ( TempBits6 == "100101") { CifradoFinal += "l"; } if ( TempBits6 == "100110") { CifradoFinal += "m"; } if ( TempBits6 == "100111") { CifradoFinal += "n"; } if ( TempBits6 == "101000") { CifradoFinal += "o"; } if ( TempBits6 == "101001") { CifradoFinal += "p"; } if ( TempBits6 == "101010") { CifradoFinal += "q"; } if ( TempBits6 == "101011") { CifradoFinal += "r"; } if ( TempBits6 == "101100") { CifradoFinal += "s"; } if ( TempBits6 == "101101") { CifradoFinal += "t"; } if ( TempBits6 == "101110") { CifradoFinal += "u"; } if ( TempBits6 == "101111") { CifradoFinal += "v"; } if ( TempBits6 == "110000") { CifradoFinal += "w"; } if ( TempBits6 == "110001") { CifradoFinal += "x"; } if ( TempBits6 == "110010") { CifradoFinal += "y"; } if ( TempBits6 == "110011") { CifradoFinal += "z"; } if ( TempBits6 == "110100") { CifradoFinal += "0"; } if ( TempBits6 == "110101") { CifradoFinal += "1"; } if ( TempBits6 == "110110") { CifradoFinal += "2"; } if ( TempBits6 == "110111") { CifradoFinal += "3"; } if ( TempBits6 == "111000") { CifradoFinal += "4"; } if ( TempBits6 == "111001") { CifradoFinal += "5"; } if ( TempBits6 == "111010") { CifradoFinal += "6"; } if ( TempBits6 == "111011") { CifradoFinal += "7"; } if ( TempBits6 == "111100") { CifradoFinal += "8"; } if ( TempBits6 == "111101") { CifradoFinal += "9"; } if ( TempBits6 == "111110") { CifradoFinal += "+"; } if ( TempBits6 == "111111") { CifradoFinal += "/"; } x = 0; TempBits6 = ""; } if ( z == CadenaDeBits6en6Tamanho ) { mantenerseEnBucle = false; } } while ( mantenerseEnBucle == true ) switch (ContadorNumDeCerosAnhadidos) { case 2: { CifradoFinal += "="; } break; case 4: { CifradoFinal += "=="; } break; } document.write(CifradoFinal); alert (CifradoFinal); </js> </body> </html>
Comentarios del código:
Los 2 switchs es parte necesaria del cifrado base64. Básicamente lo que hago es usar el operador módulo (%) para obtener el resto de dividir el tamaño del texto que se quiere cifrar entre 6 (los bits, ceros y unos, se agrupan de 6 en 6 en el cifrado base64) Como puede ser que al agrupar de 6 en 6 te queden bits sueltos, es necesario añadirle el símbolo = por cada 2bits. Con un ejemplo se ve mejor:
Si tengo los bits 1 0 0 0 1 0 1 1 y los quiero agrupar de 6 en 6. Tendré dos grupos. 100010 y 11. Lógicamente me faltan bits en el segundo grupo para tener 6 bits en ambos grupos. Entonces le añado ceros hasta tener 6 bits: 11 -> 110000
Y los simbolos igual entonces para que?
Para identificar si al número se le añadieron ceros o el número ya era así, ya que si no usamos los iguales, no podrías diferenciar cuando el texto a cifrar fue 1 0 0 0 1 0 1 1 de cuando el texo a cifrar fue 1 0 0 0 1 0 1 1 0 0 0 0.
Al no poder diferenciar tendríamos un serio problema al descifrar el cifrado y por eso se añade un igual por cada grupo de 2 bits añadidos.
Y por qué por cada 2 bits 1 igual y no por cada bit un igual? Porque solo existen 2 posibilidades. Que falten 2 bits para llegar a tener los 6 bits, o que falten 4 bits para llegar a tener los 6 bits. No tendría sentido usar 2 iguales y 4 iguales cuando podemos representar lo mismo con 1 igual y 2 iguales.
Si te parece complejo en realidad es una tontería, leete la entrada sobre el cifrado en wikipedia y lo acabarás entendiendo. Yo aprendí a implementar el cifrado usando como único recurso la wikipedia y un cifrador online psra ver si lo estaba haciendo bien.
Cuando pone case 2 en el switch del resto significa que sobraron 2 bits, por eso hay que añadirle 4 bits más para llegar a los 6.
El código dentro del bucle do while lo único que hace es añadir bits a una variable y en cuanto tiene 6 bits guarda en otra variable ese número binario pasado a caracter usando la tabla comun de base64. 000000 = A, 000001 = B, etc.
Tras obtener la cadena, vuelve a tomar los 6 siguientes bits repitiendo este proceso hasta que no queden bits que tomar.
Pueden usarse arrays para la comparación y breaks en los if para mejorar el rendimiento y reducir drásticamente las líneas del código. Pero así es más visual y fácil de entender para newbies. Lo mismo con reducir el uso de variables, etc.
Si no entendeis algo comentarlo.