js-压缩字符串

JS压缩字符串

最近项目中使用到了压缩字符串的功能,在网上查阅了很多,也有很多处理方式。有引入js库的,也有原生的方式完成的。压缩完成后的字符串乱码,如果不想要乱码的字符串可以不用查看了。

引入js库实现

使用lz-string.js文件

引入
<script type="text/javascript" src="./lz-string.min.js"></script>
使用
var string = "Lorem Ipsum is simply dummy text of the printing and typesetting industry.";
console.log("Size of sample is: " + string.length);
var compressed = LZString.compress(string);
console.log("Size of compressed sample is: " + compressed.length);
console.log(compressed);
string = LZString.decompress(compressed);
console.log("Sample is: " + string);

打印效果
js库引用展示效果

主要实现方式:压缩(LZString.compress),解压缩(LZString.decompress)

js原生实现

直接上代码

/**
* 压缩字符串
*/
function compress(strNormalString) {
  var strCompressedString = "";
  var ht = new Array();
  for (i = 0; i < 128; i++) {
      ht[i] = i;
  }

  var used = 128;
  var intLeftOver = 0;
  var intOutputCode = 0;
  var pcode = 0;
  var ccode = 0;
  var k = 0;

  for (var i = 0; i < strNormalString.length; i++) {
      ccode = strNormalString.charCodeAt(i);
      k = (pcode << 8) | ccode;
      if (ht[k] != null) {
          pcode = ht[k];
      } else {
          intLeftOver += 12;
          intOutputCode <<= 12;
          intOutputCode |= pcode;
          pcode = ccode;
          if (intLeftOver >= 16) {
              strCompressedString += String.fromCharCode(intOutputCode >> (intLeftOver - 16));
              intOutputCode &= (Math.pow(2, (intLeftOver - 16)) - 1);
              intLeftOver -= 16;
          }
          if (used < 4096) {
              used++;
              ht[k] = used - 1;
          }
      }
  }

  if (pcode != 0) {
      intLeftOver += 12;
      intOutputCode <<= 12;
      intOutputCode |= pcode;
  }

  if (intLeftOver >= 16) {
      strCompressedString += String.fromCharCode(intOutputCode >> (intLeftOver - 16));
      intOutputCode &= (Math.pow(2, (intLeftOver - 16)) - 1);
      intLeftOver -= 16;
  }

  if (intLeftOver > 0) {
      intOutputCode <<= (16 - intLeftOver);
      strCompressedString += String.fromCharCode(intOutputCode);
  }

  return strCompressedString;
}

/* *
* 解压缩字符串
*/
function decompress(strCompressedString) {
  var strNormalString = "";
  var ht = new Array();

  for (i = 0; i < 128; i++) {
      ht[i] = String.fromCharCode(i);
  }

  var used = 128;
  var intLeftOver = 0;
  var intOutputCode = 0;
  var ccode = 0;
  var pcode = 0;
  var key = 0;

  for (var i = 0; i < strCompressedString.length; i++) {
      intLeftOver += 16;
      intOutputCode <<= 16;
      intOutputCode |= strCompressedString.charCodeAt(i);

      while (1) {
          if (intLeftOver >= 12) {
              ccode = intOutputCode >> (intLeftOver - 12);
              if (typeof (key = ht[ccode]) != "undefined") {
                  strNormalString += key;
                  if (used > 128) {
                      ht[ht.length] = ht[pcode] + key.substr(0, 1);
                  }
                  pcode = ccode;
              } else {
                  key = ht[pcode] + ht[pcode].substr(0, 1);
                  strNormalString += key;
                  ht[ht.length] = ht[pcode] + key.substr(0, 1);
                  pcode = ht.length - 1;
              }

              used++;
              intLeftOver -= 12;
              intOutputCode &= (Math.pow(2, intLeftOver) - 1);
          } else {
              break;
          }
      }
  }
  return strNormalString;
}

效果图片如下
英文压缩字符展示

实现压缩中文字符串

以上两种方式不能实现压缩中文字符串,所以我最开始想的是将中文字符串转换成拼音,然后压缩,在想想拼音解压回来可能不正确。所以我最后选择的方式是将中文转换成16进制,将16进制压缩,然后解压转换

转换16进制方法如下

function chToHex(ch) { //汉字字符转16进制
    if (ch) {
        var arr = ch.split('')
        var res = ''
        for (var i = 0; i < arr.length; i++) {
            res += arr[i].charCodeAt().toString(16)
            if (i != arr.length - 1) { res += ',' }
        }
        console.log(res) // 5468,516d
        return res
    }
    return false
}
function hexToCh(ch) { //16进制转汉字
    if (ch) {
        var arr = ch.split(',')
        var res = ''
        for (var i = 0; i < arr.length; i++) {
            res += String.fromCharCode(parseInt(arr[i], 16))
        }
        console.log(res) // 周六
        return res
    }
    return false
}

具体实现的一个小demo

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>压缩字符串方法</title>
    <style type="text/css">

    </style>
</head>

<div style="text-align: center; color: cornflowerblue; height: 100%;">
    <span id="spanText">cesfafsfadsfas</span></br>
    <button onclick="changeText()">点击修改数据</button></br>
    <button onclick="reductionText()">点击还原数据</button></br>
</div>

<script type="text/javascript" src="./lz-string.min.js"></script>
<script type="text/javascript">

    // 外部jar包引用
    var string = "Lorem Ipsum is simply dummy text of the printing and typesetting industry.";
    console.log("Size of sample is: " + string.length);
    var compressed = LZString.compress(string);
    console.log("Size of compressed sample is: " + compressed.length);
    console.log(compressed);
    string = LZString.decompress(compressed);
    console.log("Sample is: " + string);

    let isChange = 0

    function changeText() {
        if (isChange === 0) {
            let text = document.getElementById('spanText').innerText
            let newText = chToHex(text)
            let changeText = compress(newText)
            document.getElementById('spanText').innerText = changeText
            isChange = 1
        } else {
            alert('当前展示文本已经压缩,请解压后操作')
            return false
        }
    }

    function reductionText() {
        if (isChange === 1) {
            let text = document.getElementById('spanText').innerText
            console.log('原始数据', text)
            let reductionText = decompress(text)
            console.log('解压完成数据', reductionText)
            let reg = new RegExp("[\\u4E00-\\u9FFF]+", "g")
            if (reg.test(reductionText)) {
                console.log('包含中文')
            }
            let newText = hexToCh(reductionText)
            document.getElementById('spanText').innerText = newText
            isChange = 0
        } else {
            alert('当前展示文本还未压缩,请压缩后操作')
            return false
        }
    }

    /**
      * 压缩字符串
      */
    function compress(strNormalString) {
        var strCompressedString = "";
        var ht = new Array();
        for (i = 0; i < 128; i++) {
            ht[i] = i;
        }

        var used = 128;
        var intLeftOver = 0;
        var intOutputCode = 0;
        var pcode = 0;
        var ccode = 0;
        var k = 0;

        for (var i = 0; i < strNormalString.length; i++) {
            ccode = strNormalString.charCodeAt(i);
            k = (pcode << 8) | ccode;
            if (ht[k] != null) {
                pcode = ht[k];
            } else {
                intLeftOver += 12;
                intOutputCode <<= 12;
                intOutputCode |= pcode;
                pcode = ccode;
                if (intLeftOver >= 16) {
                    strCompressedString += String.fromCharCode(intOutputCode >> (intLeftOver - 16));
                    intOutputCode &= (Math.pow(2, (intLeftOver - 16)) - 1);
                    intLeftOver -= 16;
                }
                if (used < 4096) {
                    used++;
                    ht[k] = used - 1;
                }
            }
        }

        if (pcode != 0) {
            intLeftOver += 12;
            intOutputCode <<= 12;
            intOutputCode |= pcode;
        }

        if (intLeftOver >= 16) {
            strCompressedString += String.fromCharCode(intOutputCode >> (intLeftOver - 16));
            intOutputCode &= (Math.pow(2, (intLeftOver - 16)) - 1);
            intLeftOver -= 16;
        }

        if (intLeftOver > 0) {
            intOutputCode <<= (16 - intLeftOver);
            strCompressedString += String.fromCharCode(intOutputCode);
        }

        return strCompressedString;
    }

    /* *
     * 解压缩字符串
     */
    function decompress(strCompressedString) {
        var strNormalString = "";
        var ht = new Array();

        for (i = 0; i < 128; i++) {
            ht[i] = String.fromCharCode(i);
        }

        var used = 128;
        var intLeftOver = 0;
        var intOutputCode = 0;
        var ccode = 0;
        var pcode = 0;
        var key = 0;

        for (var i = 0; i < strCompressedString.length; i++) {
            intLeftOver += 16;
            intOutputCode <<= 16;
            intOutputCode |= strCompressedString.charCodeAt(i);

            while (1) {
                if (intLeftOver >= 12) {
                    ccode = intOutputCode >> (intLeftOver - 12);
                    if (typeof (key = ht[ccode]) != "undefined") {
                        strNormalString += key;
                        if (used > 128) {
                            ht[ht.length] = ht[pcode] + key.substr(0, 1);
                        }
                        pcode = ccode;
                    } else {
                        key = ht[pcode] + ht[pcode].substr(0, 1);
                        strNormalString += key;
                        ht[ht.length] = ht[pcode] + key.substr(0, 1);
                        pcode = ht.length - 1;
                    }

                    used++;
                    intLeftOver -= 12;
                    intOutputCode &= (Math.pow(2, intLeftOver) - 1);
                } else {
                    break;
                }
            }
        }
        return strNormalString;
    }

    chToHex()
    hexToCh()


    function chToHex(ch) { //汉字字符转16进制
        if (ch) {
            var arr = ch.split('')
            var res = ''
            for (var i = 0; i < arr.length; i++) {
                res += arr[i].charCodeAt().toString(16)
                if (i != arr.length - 1) { res += ',' }
            }
            console.log(res) // 5468,516d
            return res
        }
        return false
    }
    function hexToCh(ch) { //16进制转汉字
        if (ch) {
            var arr = ch.split(',')
            var res = ''
            for (var i = 0; i < arr.length; i++) {
                res += String.fromCharCode(parseInt(arr[i], 16))
            }
            console.log(res) // 周六
            return res
        }
        return false
    }
</script>
</body>

</html>

展示效果
中文字符串压缩

参考博客:
十六进制转换:https://blog.csdn.net/weixin_43939111/article/details/114830133
字符串压缩:https://blog.csdn.net/qq285679784/article/details/126996720

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值