【问题标题】:HEX to Base64 converter for JavaScript用于 JavaScript 的 HEX 到 Base64 转换器
【发布时间】:2014-06-05 02:01:33
【问题描述】:

任何人都知道将 HEX 编码字符串转换为 base64 编码字符串的 JavaScript 代码的良好 sn-p 代码吗?

【问题讨论】:

  • btoa("4142434445464748494a4b4c4d4e4f505152535455565758595a".match(/\w{2}/g).map(function(a){return String.fromCharCode(parseInt(a, 16));} ).join (""))
  • @dandavis 的评论中有一个‌​(零宽度非连接符后跟一个零宽度空格),这使得截图失败并出现相当神秘的错误“SyntaxError:非法字符”在 Firefox 中,在 Chrome 中出现“SyntaxError: Unexpected token ILLEGAL”。这是固定代码:btoa("4142434445464748494a4b4c4d4e4f505152535455565758595a".match(/\w{2}/g).map(function(a){return String.fromCharCode(parseInt(a, 16));} ).join(""))
  • 更新: 我尝试在我之前的评论中粘贴一个工作版本,但似乎是 StackOverflow 添加了不可见字符——这到底是什么?!所以我想,目前唯一的解决方案是尝试将代码复制到显示此类不可见字符的编辑器(如果您手头没有,请尝试diffchecker.com)并删除罪魁祸首。那么它应该可以工作了。
  • 亲爱的@Chris Dutrow 请注意我的问题:stackoverflow.com/questions/34963963/…
  • @dandavis 出于性能原因,我会这样做:btoa(String.fromCharCode.apply(null, hex.match(/\w{2}/g).map(function(a) { return parseInt(a, 16) })))

标签: javascript string base64 hex


【解决方案1】:

大字符串,没有 btoa

以下解决方案适用于大字符串 - 如果您想从 base64 获取字节,请查看 HERE

function bytesArrToBase64(arr) {
  const abc = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; // base64 alphabet
  const bin = n => n.toString(2).padStart(8,0); // convert num to 8-bit binary string
  const l = arr.length
  let result = '';

  for(let i=0; i<=(l-1)/3; i++) {
    let c1 = i*3+1>=l; // case when "=" is on end
    let c2 = i*3+2>=l; // case when "=" is on end
    let chunk = bin(arr[3*i]) + bin(c1? 0:arr[3*i+1]) + bin(c2? 0:arr[3*i+2]);
    let r = chunk.match(/.{1,6}/g).map((x,j)=> j==3&&c2 ? '=' :(j==2&&c1 ? '=':abc[+('0b'+x)]));  
    result += r.join('');
  }

  return result;
}

function hexToBytes(hexString) {
  return hexString.match(/.{1,2}/g).map(x=> +('0x'+x));
}


// ---------
// TEST
// ---------
let hexString = "a6b580481008e60df9350de170b7e728";
let bytes = hexToBytes(hexString);
let base64 = bytesArrToBase64(bytes);

console.log(base64);

【讨论】:

    【解决方案2】:

    @dandavis 的精彩评论被 StackOverflow 修改,隐藏了一些奇怪的字符。

    这是一个班轮:

    btoa("a6b580481008e60df9350de170b7e728".match(/\w{2}/g).map(function(a){return String.fromCharCode(parseInt(a, 16));} ).join(""))
    

    或:

    function hexToBase64(hexstring) {
        return btoa(hexstring.match(/\w{2}/g).map(function(a) {
            return String.fromCharCode(parseInt(a, 16));
        }).join(""));
    }
    
    hexToBase64("a6b580481008e60df9350de170b7e728");
    

    两者都返回:

    "prWASBAI5g35NQ3hcLfnKA=="
    

    注意十六进制字符串的长度应该是偶数:

    hexToBase64("00");
    // => "AA=="
    hexToBase64("000");
    // => "AA=="
    

    【讨论】:

    • 为什么00 返回AA?它应该只返回 0
    • 如果长度为奇数也会丢失一个字符hexToBase64('ab') === hexToBase64('abc')
    • @CristianTraìna:据我所知,base64 AA== 是十六进制 00 的预期输出。每个其他函数返回相同。接受奇数长度十六进制输入的函数似乎填充了十六进制数字,例如:base64ToHex(hexToBase64('000')) // =&gt; "00 00"。我将编辑答案以指定输入的长度应该是偶数。
    【解决方案3】:

    我喜欢@eric-duminil 的方法,但下面的解决方案 - 避免使用正则表达式 - 速度快了约 2 倍。

    浏览器:

    function hexToBase64(hexStr) {
      return btoa([...hexStr].reduce((acc, _, i) =>
        acc += !(i - 1 & 1) ? String.fromCharCode(parseInt(hexStr.substring(i - 1, i + 1), 16)) : "" 
      ,""));
    }
    

    // even a bit faster
    function hexToBase64(hexStr) {
     let base64 = "";
     for(let i = 0; i < hexStr.length; i++) {
       base64 += !(i - 1 & 1) ? String.fromCharCode(parseInt(hexStr.substring(i - 1, i + 1), 16)) : ""
     }
     return btoa(base64);
    }
    

    节点:

    const base64 = Buffer.from(hexStr, 'hex').toString('base64');
    

    【讨论】:

      【解决方案4】:

      如果你在 Node 中工作或使用 Browserify,你可以使用

      var base64String = Buffer.from(hexString, 'hex').toString('base64')
      

      var hexString = Buffer.from(base64String, 'base64').toString('hex')
      

      【讨论】:

      • 节省了我多半天的代码,如果没有这些知识,这些代码会被丢弃。
      【解决方案5】:
      if (!window.atob) {
        var tableStr = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
        var table = tableStr.split("");
      
        window.atob = function (base64) {
          if (/(=[^=]+|={3,})$/.test(base64)) throw new Error("String contains an invalid character");
          base64 = base64.replace(/=/g, "");
          var n = base64.length & 3;
          if (n === 1) throw new Error("String contains an invalid character");
          for (var i = 0, j = 0, len = base64.length / 4, bin = []; i < len; ++i) {
            var a = tableStr.indexOf(base64[j++] || "A"), b = tableStr.indexOf(base64[j++] || "A");
            var c = tableStr.indexOf(base64[j++] || "A"), d = tableStr.indexOf(base64[j++] || "A");
            if ((a | b | c | d) < 0) throw new Error("String contains an invalid character");
            bin[bin.length] = ((a << 2) | (b >> 4)) & 255;
            bin[bin.length] = ((b << 4) | (c >> 2)) & 255;
            bin[bin.length] = ((c << 6) | d) & 255;
          };
          return String.fromCharCode.apply(null, bin).substr(0, bin.length + n - 4);
        };
      
        window.btoa = function (bin) {
          for (var i = 0, j = 0, len = bin.length / 3, base64 = []; i < len; ++i) {
            var a = bin.charCodeAt(j++), b = bin.charCodeAt(j++), c = bin.charCodeAt(j++);
            if ((a | b | c) > 255) throw new Error("String contains an invalid character");
            base64[base64.length] = table[a >> 2] + table[((a << 4) & 63) | (b >> 4)] +
                                    (isNaN(b) ? "=" : table[((b << 2) & 63) | (c >> 6)]) +
                                    (isNaN(b + c) ? "=" : table[c & 63]);
          }
          return base64.join("");
        };
      
      }
      
      function hexToBase64(str) {
        return btoa(String.fromCharCode.apply(null,
          str.replace(/\r|\n/g, "").replace(/([\da-fA-F]{2}) ?/g, "0x$1 ").replace(/ +$/, "").split(" "))
        );
      }
      
      function base64ToHex(str) {
        for (var i = 0, bin = atob(str.replace(/[ \r\n]+$/, "")), hex = []; i < bin.length; ++i) {
          var tmp = bin.charCodeAt(i).toString(16);
          if (tmp.length === 1) tmp = "0" + tmp;
          hex[hex.length] = tmp;
        }
        return hex.join(" ");
      }
      

      【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-12-13
      • 2021-04-28
      • 1970-01-01
      • 1970-01-01
      • 2013-03-28
      • 2017-11-21
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多