使用 javascript 将 Base64 解码为十六进制字符串
Decode Base64 to Hexadecimal string with javascript
需要使用 javascript.
将 Base64 字符串转换为十六进制
示例:
var base64Value = "oAAABTUAAg=="
需要转换方法
输出(解码数据(十六进制))A0000005350002
我知道这是正确的,因为我可以使用这个网站http://tomeko.net/online_tools/base64.php?lang=en
打入oAAABTUAAg==
的Base64字符串得到A0000005350002
我尝试了什么?
https://github.com/carlo/jquery-base64
https://jsfiddle.net/gabrieleromanato/qaght/
我发现了很多问题
atob() 然后 charCodeAt() 会给你二进制 & toString(16) 会给你十六进制。
function base64ToHex(str) {
const raw = atob(str);
let result = '';
for (let i = 0; i < raw.length; i++) {
const hex = raw.charCodeAt(i).toString(16);
result += (hex.length === 2 ? hex : '0' + hex);
}
return result.toUpperCase();
}
console.log(base64ToHex("oAAABTUAAg=="));
假设您希望十六进制表示为字符串,window.atob
function(在大多数现代浏览器中可用)是您的第一步 - 它将您的 base64 字符串转换为 ASCII 字符串,其中每个字符代表一个字节.
此时您拆分字符串,获取每个字符的字符代码,然后将 that 转换为左填充的 base-16 字符串。
function base64ToBase16(base64) {
return window.atob(base64)
.split('')
.map(function (aChar) {
return ('0' + aChar.charCodeAt(0).toString(16)).slice(-2);
})
.join('')
.toUpperCase(); // Per your example output
}
console.log(base64ToBase16("oAAABTUAAg==")); // "A0000005350002"
为什么不试试下面的代码呢?:
const buffer = Buffer.from(rawData, 'base64');
const bufString = buffer.toString('hex');
这是我的原始 JavaScript 解决方案,它不使用 atob
和 Buffer
。
支持分隔符,适用于二进制数据和React Native,性能相对较高。
用法:
base64ToHex( 'MTIzYWJjIDotKQ==', '-' )
// returns '31-32-33-61-62-63-20-3a-2d-29'
代码:
/* Convert base64 data to hex string.
* txt : Base64 string.
* sep : Hex separator, e.g. '-' for '1a-2b-3c'. Default empty.
*/
const base64ToHex = ( () => {
// Lookup tables
const values = [], output = [];
// Main converter
return function base64ToHex ( txt, sep = '' ) {
if ( output.length <= 0 ) populateLookups();
const result = [];
let v1, v2, v3, v4;
for ( let i = 0, len = txt.length ; i < len ; i += 4 ) {
// Map four chars to values.
v1 = values[ txt.charCodeAt( i ) ];
v2 = values[ txt.charCodeAt( i+1 ) ];
v3 = values[ txt.charCodeAt( i+2 ) ];
v4 = values[ txt.charCodeAt( i+3 ) ];
// Split and merge bits, then map and push to output.
result.push(
output[ ( v1 << 2) | (v2 >> 4) ],
output[ ((v2 & 15) << 4) | (v3 >> 2) ],
output[ ((v3 & 3) << 6) | v4 ]
);
}
// Trim result if the last values are '='.
if ( v4 === 64 ) result.splice( v3 === 64 ? -2 : -1 );
return result.join( sep );
};
function populateLookups () {
const keys = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=';
for ( let i = 0 ; i < 256 ; i++ ) {
output.push( ( '0' + i.toString( 16 ) ).slice( -2 ) );
values.push( 0 );
}
for ( let i = 0 ; i < 65 ; i++ )
values[ keys.charCodeAt( i ) ] = i;
}
} )();
演示:
const [ txt, b64, hex, sep ] = document.querySelectorAll( 'input, select' );
function txtOnInput ({ target: { value }}) {
hex.value = base64ToHex( b64.value = btoa( value ), sep.value ).toUpperCase();
}
function b64OnInput ({ target: { value }}) {
hex.value = base64ToHex( value, sep.value ).toUpperCase();
txt.value = atob( value );
}
txtOnInput({target:txt});
// Different coding style, same result.
function base64ToHex ( txt, sep = '' ) {
let { val, out } = base64ToHex, v1, v2, v3, v4, result = [];
if ( ! base64ToHex.val ) { // Populate lookup tables.
out = base64ToHex.out = [];
val = base64ToHex.val = Array( 255 ).fill( 0 );
const keys = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=';
for ( let i = 0 ; i < 256 ; i++ ) out.push( ( '0' + i.toString(16) ).slice( -2 ) );
for ( let i = 0 ; i < 65 ; i++ ) val[ keys.charCodeAt( i ) ] = i;
}
for ( let i = 0, len = txt.length ; i < len ; i += 4 ) {
v1 = val[ txt.charCodeAt( i ) ]; // Map four chars to values.
v2 = val[ txt.charCodeAt( i+1 ) ];
v3 = val[ txt.charCodeAt( i+2 ) ];
v4 = val[ txt.charCodeAt( i+3 ) ];
result.push( out[ (v1 << 2) | (v2 >> 4) ], // Split values, map to output.
out[ ((v2 & 15) << 4) | (v3 >> 2) ],
out[ ((v3 & 3) << 6) | v4 ] );
} // After loop ended: Trim result if the last values are '='.
if ( v4 === 64 ) result.splice( v3 === 64 ? -2 : -1 );
return result.join( sep ); // Array is fast. String append = lots of copying.
}
label { display: block; height: 1em; }
input, select { position: absolute; left: 5em; width: calc( 100% - 6em ) }
input[readonly] { background: #D8D8D8; }
<label>Ascii <input oninput='txtOnInput(event)' value='123abc :-)'></label><br>
<label>Base64 <input oninput='b64OnInput(event)'></label><br>
<label>Hex <input readonly></label><br>
<label> <select onchange='txtOnInput({target:txt})'>
<option value=''>(None)<option value=' ' selected>(Space)<option value='-'>-</select></label><br>
注意:这样做是为了 geisterfurz007 because react-native-fs 为二进制文件生成 base64,并且他需要将其转换为十六进制字符串。
并不是说我对现有片段的效率感到满意...
尝试
[...atob(base64Value)].map(c=> c.charCodeAt(0).toString(16).padStart(2,0))
let base64Value = "oAAABTUAAg=="
let h= [...atob(base64Value)].map(c=> c.charCodeAt(0).toString(16).padStart(2,0))
console.log( h.join``.toUpperCase() );
需要使用 javascript.
将 Base64 字符串转换为十六进制示例:
var base64Value = "oAAABTUAAg=="
需要转换方法
输出(解码数据(十六进制))A0000005350002
我知道这是正确的,因为我可以使用这个网站http://tomeko.net/online_tools/base64.php?lang=en
打入oAAABTUAAg==
的Base64字符串得到A0000005350002
我尝试了什么?
https://github.com/carlo/jquery-base64
https://jsfiddle.net/gabrieleromanato/qaght/
我发现了很多问题
atob() 然后 charCodeAt() 会给你二进制 & toString(16) 会给你十六进制。
function base64ToHex(str) {
const raw = atob(str);
let result = '';
for (let i = 0; i < raw.length; i++) {
const hex = raw.charCodeAt(i).toString(16);
result += (hex.length === 2 ? hex : '0' + hex);
}
return result.toUpperCase();
}
console.log(base64ToHex("oAAABTUAAg=="));
假设您希望十六进制表示为字符串,window.atob
function(在大多数现代浏览器中可用)是您的第一步 - 它将您的 base64 字符串转换为 ASCII 字符串,其中每个字符代表一个字节.
此时您拆分字符串,获取每个字符的字符代码,然后将 that 转换为左填充的 base-16 字符串。
function base64ToBase16(base64) {
return window.atob(base64)
.split('')
.map(function (aChar) {
return ('0' + aChar.charCodeAt(0).toString(16)).slice(-2);
})
.join('')
.toUpperCase(); // Per your example output
}
console.log(base64ToBase16("oAAABTUAAg==")); // "A0000005350002"
为什么不试试下面的代码呢?:
const buffer = Buffer.from(rawData, 'base64');
const bufString = buffer.toString('hex');
这是我的原始 JavaScript 解决方案,它不使用 atob
和 Buffer
。
支持分隔符,适用于二进制数据和React Native,性能相对较高。
用法:
base64ToHex( 'MTIzYWJjIDotKQ==', '-' )
// returns '31-32-33-61-62-63-20-3a-2d-29'
代码:
/* Convert base64 data to hex string.
* txt : Base64 string.
* sep : Hex separator, e.g. '-' for '1a-2b-3c'. Default empty.
*/
const base64ToHex = ( () => {
// Lookup tables
const values = [], output = [];
// Main converter
return function base64ToHex ( txt, sep = '' ) {
if ( output.length <= 0 ) populateLookups();
const result = [];
let v1, v2, v3, v4;
for ( let i = 0, len = txt.length ; i < len ; i += 4 ) {
// Map four chars to values.
v1 = values[ txt.charCodeAt( i ) ];
v2 = values[ txt.charCodeAt( i+1 ) ];
v3 = values[ txt.charCodeAt( i+2 ) ];
v4 = values[ txt.charCodeAt( i+3 ) ];
// Split and merge bits, then map and push to output.
result.push(
output[ ( v1 << 2) | (v2 >> 4) ],
output[ ((v2 & 15) << 4) | (v3 >> 2) ],
output[ ((v3 & 3) << 6) | v4 ]
);
}
// Trim result if the last values are '='.
if ( v4 === 64 ) result.splice( v3 === 64 ? -2 : -1 );
return result.join( sep );
};
function populateLookups () {
const keys = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=';
for ( let i = 0 ; i < 256 ; i++ ) {
output.push( ( '0' + i.toString( 16 ) ).slice( -2 ) );
values.push( 0 );
}
for ( let i = 0 ; i < 65 ; i++ )
values[ keys.charCodeAt( i ) ] = i;
}
} )();
演示:
const [ txt, b64, hex, sep ] = document.querySelectorAll( 'input, select' );
function txtOnInput ({ target: { value }}) {
hex.value = base64ToHex( b64.value = btoa( value ), sep.value ).toUpperCase();
}
function b64OnInput ({ target: { value }}) {
hex.value = base64ToHex( value, sep.value ).toUpperCase();
txt.value = atob( value );
}
txtOnInput({target:txt});
// Different coding style, same result.
function base64ToHex ( txt, sep = '' ) {
let { val, out } = base64ToHex, v1, v2, v3, v4, result = [];
if ( ! base64ToHex.val ) { // Populate lookup tables.
out = base64ToHex.out = [];
val = base64ToHex.val = Array( 255 ).fill( 0 );
const keys = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=';
for ( let i = 0 ; i < 256 ; i++ ) out.push( ( '0' + i.toString(16) ).slice( -2 ) );
for ( let i = 0 ; i < 65 ; i++ ) val[ keys.charCodeAt( i ) ] = i;
}
for ( let i = 0, len = txt.length ; i < len ; i += 4 ) {
v1 = val[ txt.charCodeAt( i ) ]; // Map four chars to values.
v2 = val[ txt.charCodeAt( i+1 ) ];
v3 = val[ txt.charCodeAt( i+2 ) ];
v4 = val[ txt.charCodeAt( i+3 ) ];
result.push( out[ (v1 << 2) | (v2 >> 4) ], // Split values, map to output.
out[ ((v2 & 15) << 4) | (v3 >> 2) ],
out[ ((v3 & 3) << 6) | v4 ] );
} // After loop ended: Trim result if the last values are '='.
if ( v4 === 64 ) result.splice( v3 === 64 ? -2 : -1 );
return result.join( sep ); // Array is fast. String append = lots of copying.
}
label { display: block; height: 1em; }
input, select { position: absolute; left: 5em; width: calc( 100% - 6em ) }
input[readonly] { background: #D8D8D8; }
<label>Ascii <input oninput='txtOnInput(event)' value='123abc :-)'></label><br>
<label>Base64 <input oninput='b64OnInput(event)'></label><br>
<label>Hex <input readonly></label><br>
<label> <select onchange='txtOnInput({target:txt})'>
<option value=''>(None)<option value=' ' selected>(Space)<option value='-'>-</select></label><br>
注意:这样做是为了 geisterfurz007 because react-native-fs 为二进制文件生成 base64,并且他需要将其转换为十六进制字符串。 并不是说我对现有片段的效率感到满意...
尝试
[...atob(base64Value)].map(c=> c.charCodeAt(0).toString(16).padStart(2,0))
let base64Value = "oAAABTUAAg=="
let h= [...atob(base64Value)].map(c=> c.charCodeAt(0).toString(16).padStart(2,0))
console.log( h.join``.toUpperCase() );