Skip to content

Instantly share code, notes, and snippets.

@Fujihai
Last active October 12, 2020 15:28
Show Gist options
  • Save Fujihai/bc3cb0da52207694c5a0b92ade15cd94 to your computer and use it in GitHub Desktop.
Save Fujihai/bc3cb0da52207694c5a0b92ade15cd94 to your computer and use it in GitHub Desktop.
位运算+二进制实现URL参数压缩
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
<script>
// 基础变量
var encodeMapChar = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ_-';
// 函数调用测试
console.log(`days2dateStr(7400): `, days2dateStr(7400));
console.log(`getDays("20200410"): `, getDays("20200410"));
console.log(`encodeDateStr("20200301", "20200307", "20200308", "20200315")`,
encodeDateStr("20200301", "20200307", "20200308", "20200315"));
console.log(`decodeDateStr("sNhPbsP1Pj"):`, decodeDateStr("sNhPbsP1Pj"));
console.log(`string10to64(138870): `, string10to64(138870));
/**
* 64 进制数转 10 进制
*/
function string64to10(numberCode) {
var radix = encodeMapChar.length;
numberCode = String(numberCode);
var len = numberCode.length,
i = 0,
originNumber = 0;
while (i < len) {
originNumber += Math.pow(radix, i++) * encodeMapChar.indexOf(numberCode.charAt(len - i) || 0);
}
return originNumber;
}
/**
* 10 进制数转换成 64 进制
*/
function string10to64(number) {
var radix = encodeMapChar.length,
qutient = +number,
arr = [];
do {
var mod = qutient % radix;
qutient = (qutient - mod) / radix;
arr.unshift(encodeMapChar[mod]);
} while (qutient);
return arr.join('');
}
/**
*  10 进制数转换成 64 进制数,并设置最小长度
*  若转换数值长度小于 len 长度,高位补 0,否则不做处理
*/
function encodeNlen(intNum, len) {
var tmp = string10to64(intNum);
var curLen = tmp.length;
for (var i = curLen; i < len; i++) {
tmp = '0' + tmp;
}
return tmp;
}
/**
* 返回距离 2000 年 1 月 1 日,天数为 days 的当前日期,格式为 YYYYMMDD 类型
* 比如:20200301
*/
function days2dateStr(days) {
var baseDate = new Date(2000, 0, 1, 0, 0, 0, 0);
var resDate = new Date(baseDate.getTime() + days * 24 * 60 * 60 * 1000);
var year = resDate.getFullYear();
var month = resDate.getMonth() + 1;
var day = resDate.getDate();
month = month < 10 ? '0' + month : month;
day = day < 10 ? '0' + day : day;
return `${year}${month}${day};
}
/**
* 计算当前日期与 2000 年 1 月 1 日之间相差的天数
* 参数日期格式: 20200410
*/
function getDays(curDateStr) {
var baseDate = new Date(2000, 0, 1, 0, 0, 0);
var year = parseInt(curDateStr.substr(0, 4));
var month = parseInt(curDateStr.substr(4, 2));
var day = parseInt(curDateStr.substr(6, 2));
month = month > 0 ? (month - 1) : 0;
var curDate = new Date(year, month, day, 0, 0, 0);
var days = (curDate.getTime() - baseDate.getTime()) / (24 * 60 * 60 * 1000);
return days;
}
/**
* 日期字符串编码
*/
function encodeDateStr(oneDt, twoDt, threeDt, fourDt) {
var oneDtDays = getDays(oneDt);
var twoDtDays = getDays(twoDt);
var threeDtDays = getDays(threeDt);
var fourDtDays = getDays(fourDt);
// 高 16 位存放 oneDtDays, 低 16 位存放 twoDtDays
var left = (oneDtDays << 16) + twoDtDays;
var right = (threeDtDays << 16) + fourDtDays;
return encodeNlen(left, 5) + encodeNlen(right, 5);
}
function decodeDateStr(encodeStr) {
var left = string64to10(encodeStr.substring(0, 5));
var right = string64to10(encodeStr.substring(5, 10));
var oneDt = left >> 16;
var twoDt = left & 0xFFFF;
var threeDt = right >> 16;
var fourDt = right & 0xFFFF;
return [this.days2dateStr(oneDt), this.days2dateStr(twoDt),
this.days2dateStr(threeDt), this.days2dateStr(fourDt)];
}
</script>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment