Last active
October 12, 2020 15:28
-
-
Save Fujihai/bc3cb0da52207694c5a0b92ade15cd94 to your computer and use it in GitHub Desktop.
位运算+二进制实现URL参数压缩
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!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