online nodejs imagen decodificar convertir codificacion btoa javascript

nodejs - ¿La forma más rápida de convertir un número a radix 64 en JavaScript?



decodificar imagen base64 javascript (11)

En JavaScript, puede convertir un número en una representación de cadena con una radix específica de la siguiente manera:

(12345).toString(36) // "9ix"

... y puedes convertirlo a un número regular como este:

parseInt("9ix", 36) // 12345

36 es la raíz más alta que puede especificar. Aparentemente usa los caracteres 0-9 y az para los dígitos (36 en total).

Mi pregunta: ¿cuál es la forma más rápida de convertir un número a una representación base 64 (por ejemplo, usando AZ , y - y _ para los 28 dígitos adicionales)?

Actualización : cuatro personas han publicado respuestas diciendo que esta pregunta está duplicada, o que estoy buscando Base64. No soy.

" Base64 " es una forma de codificar datos binarios en un juego de caracteres ASCII simple, para que sea seguro para la transferencia a través de redes, etc. (de modo que los sistemas solo de texto no distorsionen el binario).

Eso no es lo que estoy preguntando. Estoy preguntando sobre la conversión de números a una representación de 64 cadenas. (JavaScript toString(radix) hace esto automáticamente para cualquier raíz hasta 36; necesito una función personalizada para obtener radix 64.)

Actualización 2 : Aquí hay algunos ejemplos de entrada y salida ...

0 → "0" 1 → "1" 9 → "9" 10 → "a" 35 → "z" 61 → "Z" 62 → "-" 63 → "_" 64 → "10" 65 → "11" 128 → "20" etc.


Aquí hay un boceto de una solución para NUMBERS (no matrices de bytes :)

solo para números positivos, ignora partes fraccionarias, y no realmente probado, ¡solo un boceto!

Base64 = { _Rixits : // 0 8 16 24 32 40 48 56 63 // v v v v v v v v v "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz+/", // You have the freedom, here, to choose the glyphs you want for // representing your base-64 numbers. The ASCII encoding guys usually // choose a set of glyphs beginning with ABCD..., but, looking at // your update #2, I deduce that you want glyphs beginning with // 0123..., which is a fine choice and aligns the first ten numbers // in base 64 with the first ten numbers in decimal. // This cannot handle negative numbers and only works on the // integer part, discarding the fractional part. // Doing better means deciding on whether you''re just representing // the subset of javascript numbers of twos-complement 32-bit integers // or going with base-64 representations for the bit pattern of the // underlying IEEE floating-point number, or representing the mantissae // and exponents separately, or some other possibility. For now, bail fromNumber : function(number) { if (isNaN(Number(number)) || number === null || number === Number.POSITIVE_INFINITY) throw "The input is not valid"; if (number < 0) throw "Can''t represent negative numbers now"; var rixit; // like ''digit'', only in some non-decimal radix var residual = Math.floor(number); var result = ''''; while (true) { rixit = residual % 64 // console.log("rixit : " + rixit); // console.log("result before : " + result); result = this._Rixits.charAt(rixit) + result; // console.log("result after : " + result); // console.log("residual before : " + residual); residual = Math.floor(residual / 64); // console.log("residual after : " + residual); if (residual == 0) break; } return result; }, toNumber : function(rixits) { var result = 0; // console.log("rixits : " + rixits); // console.log("rixits.split('''') : " + rixits.split('''')); rixits = rixits.split(''''); for (var e = 0; e < rixits.length; e++) { // console.log("_Rixits.indexOf(" + rixits[e] + ") : " + // this._Rixits.indexOf(rixits[e])); // console.log("result before : " + result); result = (result * 64) + this._Rixits.indexOf(rixits[e]); // console.log("result after : " + result); } return result; } }

ACTUALIZACIÓN: Aquí hay algunas pruebas (muy livianas) de lo anterior, para ejecutar en NodeJs donde tiene console.log.

function testBase64(x) { console.log("My number is " + x); var g = Base64.fromNumber(x); console.log("My base-64 representation is " + g); var h = Base64.toNumber(g); console.log("Returning from base-64, I get " + h); if (h !== Math.floor(x)) throw "TEST FAILED"; } testBase64(0); try { testBase64(-1); } catch (err) { console.log("caught >>>>>> " + err); } try { testBase64(undefined); } catch (err) { console.log("caught >>>>>> " + err); } try { testBase64(null); } catch (err) { console.log("caught >>>>>> " + err); } try { testBase64(Number.NaN); } catch (err) { console.log("caught >>>>>> " + err); } try { testBase64(Number.POSITIVE_INFINITY); } catch (err) { console.log("caught >>>>>> " + err); } try { testBase64(Number.NEGATIVE_INFINITY); } catch (err) { console.log("caught >>>>>> " + err); } for(i=0; i<100; i++) testBase64(Math.random()*1e14);


Aquí hay una toma diferente

function base64(value) { if (typeof(value) === ''number'') { return base64.getChars(value, ''''); } if (typeof(value) === ''string'') { if (value === '''') { return NaN; } return value.split('''').reverse().reduce(function(prev, cur, i) { return prev + base64.chars.indexOf(cur) * Math.pow(64, i); }, 0); } } base64.chars = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz-_"; base64.getChars = function(num, res) { var mod = num % 64, remaining = Math.floor(num / 64), chars = base64.chars.charAt(mod) + res; if (remaining <= 0) { return chars; } return base64.getChars(remaining, chars); };


Aquí hay una versión para entradas de 32 bits, es decir, cualquier número entre -2147483648 y 2147483647 (inclusive).

Modifiqué la versión en la respuesta superior por Reb Cabin. Esto debería ser bastante más rápido porque usa operaciones de bits y tablas de búsqueda.

Base64 = (function () { var digitsStr = // 0 8 16 24 32 40 48 56 63 // v v v v v v v v v "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz+-"; var digits = digitsStr.split(''''); var digitsMap = {}; for (var i = 0; i < digits.length; i++) { digitsMap[digits[i]] = i; } return { fromInt: function(int32) { var result = ''''; while (true) { result = digits[int32 & 0x3f] + result; int32 >>>= 6; if (int32 === 0) break; } return result; }, toInt: function(digitsStr) { var result = 0; var digits = digitsStr.split(''''); for (var i = 0; i < digits.length; i++) { result = (result << 6) + digitsMap[digits[i]]; } return result; } }; })();

Por ejemplo,

Base64.fromInt(-2147483648); // gives "200000" Base64.toInt("200000"); // gives -2147483648


Bueno, podrías usar cualquier biblioteca Javascript Base64: tal vez esta pregunta la responda?

EDITAR: Los datos binarios son esencialmente solo una secuencia de bytes. Si supone que los bytes representan un solo número, puede representar la secuencia de bytes como una cadena base 64. Decodifícalos y haz algunas matemáticas triviales en los bytes para obtener un número. Convierte el número en una secuencia de bytes y codifica para obtener una cadena. Parece bastante razonable, a menos que de alguna manera se invierta en los caracteres específicos utilizados en el String.


En un navegador mozilla o webkit puede usar btoa () y atob () para codificar y decodificar base64.


Escribí un módulo npm para este tipo de operación, power-radix , que te ayudará. Puede convertir cualquier número desde cualquier raíz a cualquier raíz en una codificación de caracteres definida por el usuario.

Por ejemplo:

var base = [''Q'', ''W'', ''E'', ''R'', ''T'', ''Y'', ''I'', ''O'', ''U'']; new PowerRadix([1, 0], 10).toArray(base); // [''W'', ''Q''] new PowerRadix(''10'', 10).toArray(base); // [''W'', ''Q''] new PowerRadix(10, 10).toArray(base); // [''W'', ''Q''] new PowerRadix([1, 0], 10).toString(base); // "WQ" new PowerRadix(''10'', 10).toString(base); // "WQ" new PowerRadix(10, 10).toString(base); // "WQ"

El módulo también es compatible con codificaciones de raíz de origen personalizadas.

new PowerRadix(''ba'', [''a'', ''b'']); // base 2 source radix, uses ''a'' = 0 & ''b'' = 1 character set. new PowerRadix(''ba'', [''a'', ''b'']).toString(10); // returns "2"


Estaba buscando una solución para el mismo problema, pero para ActionScript (AS3) , y era evidente que muchas personas confunden la codificación Base64 con ''números en la base 64'' (raíz 64) .

La gran mayoría de los sitios ofrecen soluciones para ''criptografía computacional'' y no para matemáticas . Como soluciones, esto no es útil para la conversión que necesitábamos.

Antes de esta consulta, y conocía los métodos toString (radix) y parseInt (radix), trabajé con números hexadecimales (radix 16) en ambos colores y en otras características.

Sin embargo, ni en AS3 ni en JS existe un método numérico para transformaciones hacia y desde radix 64.

Antes de llegar a este sitio, encontré:

  1. En varias calculadoras en línea, radix 64 no comienza desde cero, pero A.
    Por ejemplo: convertix.com y alfredo4570.net
  2. En radix 64 está formado por los siguientes conjuntos de caracteres ordenados: AZ, az, 0-9, + y / (estos he definido una constante: STR64)

Para evitar confusiones con los métodos criptográficos, los métodos que se utilizarán se basan en nombres bien conocidos:

  • toString / to64String
  • parseInt / to64Parse

El código se escribió en AS3 , pero es muy claro (común con JS).

NOTA: Uso recomendado con el número debajo: 1 * 10 16

Al final, se incluyen un ejemplo y los resultados de las operaciones.

const STR64:Array = (''ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'').split( '''' ); // TRANSFORM NUMBERS BETWEEN radix 10 AND radix 64 /** Methods based on answers shared in: * @url http://.com/questions/6213227/fastest-way-to-convert-a-number-to-radix-64-in-javascript */ // METHODS /** to64String: Method to transform a radix 10 number to radix 64 number (as string) * @param input Number for transform to radix 64 (as String) * @param current String data (don''t needed in request) * @return String Number in radix 64 as String; * * @based http://.com/users/383780/monocle * @based base64( Method for number to string - NOT string part ) */ function to64String( input:Number, current:String = '''' ):String { if ( input < 0 && current.length == 0 ){ input = input * - 1; } var modify:Number = input % 64; var remain:Number = Math.floor( input / 64 ); var result:String = STR64[ modify ] + current; return ( remain <= 0 ) ? result : to64String( remain, result ); } /** to64Parse: Method for transform a number in radix 64 (as string) in radix 10 number * @param input Number in radix 64 (as String) to transform in radix 10 * @return Number in radix 10 * * @based http://.com/users/520997/reb-cabin * @based Base64.toNumber( Method for string to number ) */ function to64Parse ( input:String ):Number { var result:Number = 0; var toProc:Array = input.split( '''' ); var e:String; for ( e in toProc ){ result = ( result * 64 ) + STR64.indexOf( toProc[ e ] ); } return result; } // TEST var i:int = 0; var max:Number = 1000000000000; var min:Number = 0; for ( i == 0; i < 20; i++ ){ var num:Number = ( Math.ceil( Math.random() * ( max - min + 1 ) ) + min ); var s64:String = to64String( num ); var ret:Number = to64Parse ( s64 ); trace( i + ''/t# '' + num + ''/t'' + s64 + ''/t'' + ret + ''/t'' + ( ret == num ) ) } // TEST RESULT /* 0 # 808936734685 LxYYv/d 808936734685 true 1 # 931332556532 NjXvwb0 931332556532 true 2 # 336368837395 E5RJSMT 336368837395 true 3 # 862123347820 Mi6jk9s 862123347820 true 4 # 174279278611 CiT2sAT 174279278611 true 5 # 279361353722 EELO/f6 279361353722 true 6 # 435602995568 GVr9jlw 435602995568 true 7 # 547163526063 H9lfNOv 547163526063 true 8 # 188017380425 CvGtYxJ 188017380425 true 9 # 720098771622 KepO0Km 720098771622 true 10 # 408089106903 F8EAZnX 408089106903 true 11 # 293941423763 ERwRi6T 293941423763 true 12 # 383302396164 Fk+mmkE 383302396164 true 13 # 695998940618 KIMxQXK 695998940618 true 14 # 584515331314 IgX1CTy 584515331314 true 15 # 528965753970 Hso0Nxy 528965753970 true 16 # 5324317143 E9WqHX 5324317143 true 17 # 772389841267 LPWBalz 772389841267 true 18 # 954212692102 N4rgjCG 954212692102 true 19 # 867031893694 MnfIMa+ 867031893694 true */


Implementación extremadamente rápida para todos los valores de rango de enteros seguros de JavaScript (desde -9007199254740991 hasta 9007199254740991 ):

const alphabet = ''ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/''; // binary to string lookup table const b2s = alphabet.split(''''); // string to binary lookup table // 123 == ''z''.charCodeAt(0) + 1 const s2b = new Array(123); for (let i = 0; i < alphabet.length; i++) { s2b[alphabet.charCodeAt(i)] = i; } // number to base64 const ntob = (number) => { if (number < 0) return `-${ntob(-number)}`; let lo = number >>> 0; let hi = (number / 4294967296) >>> 0; let right = ''''; while (hi > 0) { right = b2s[0x3f & lo] + right; lo >>>= 6; lo |= (0x3f & hi) << 26; hi >>>= 6; } let left = ''''; do { left = b2s[0x3f & lo] + left; lo >>>= 6; } while (lo > 0); return left + right; }; // base64 to number const bton = (base64) => { let number = 0; const sign = base64.charAt(0) === ''-'' ? 1 : 0; for (let i = sign; i < base64.length; i++) { number = number * 64 + s2b[base64.charCodeAt(i)]; } return sign ? -number : number; };

npm: number-to-base64

Comparación de rendimiento: https://jsperf.com/number-to-base64-encoding


La siguiente implementación convierte números positivos, negativos y no enteros en una base arbitraria. La conversión de nuevo a decimal se implementa fácilmente de una manera similar:

function toAnyBase(num, base) { if (!Number.isInteger(base) || base < 2) throw new RangeError("toAnyBase() base argument must be an integer >= 2"); if (!Number.isFinite(num)) return num.toString(); if (num < 0) return "-" + toAnyBase(-num, base); const digits = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ#_", inv_base = 1 / base; var result = "", residual; // Integer part: residual = Math.trunc(num); do { result = digits.charAt(residual % base) + result; residual = Math.trunc(residual * inv_base); } while (residual != 0); // Fractional part: residual = num % 1; if (residual != 0) { result += "."; var max = 1000; do { residual *= base; result += digits.charAt(Math.trunc(residual)); residual %= 1; } while (residual != 0 && --max != 0); } return result; } console.log(toAnyBase( 64, 64)); // "10" console.log(toAnyBase(-1.5, 64)); // "-1.w"


Sé que la pregunta es Java Script, pero aquí hay una solución en Java, probablemente puedas convertirla fácilmente.

private String toShortString(BigInteger value, String language) { StringBuilder stringBuilder = new StringBuilder(); BigInteger length = BigInteger.valueOf(language.length()); while (value.compareTo(BigInteger.ZERO) > 0){ int index = value.mod(length).intValue(); stringBuilder.append(language.charAt(index)); value = value.divide(length); } return stringBuilder.reverse().toString(); }

Uso

BigInteger value = BigInteger.valueOf(2).pow(128); System.out.println(value); System.out.println(value.toString(16)); System.out.println(toShortString(value, "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ!@#$%^&*()-=_+"));

Salida

340282366920938463463374607431768211456
100000000000000000000000000000000
8hS # phQaCO3849pE + ^ El4

Si convierte esto a Java Script, edite esta pregunta y agréguela a continuación.


Si está utilizando NodeJS, puede usar el siguiente código:

var base64 = Buffer.from([i>>24,i>>16,i>>8,i]).toString(''base64'').substr(0,6);