当前位置:网站首页>编码与进制
编码与进制
2022-07-30 22:16:00 【张子虚】
编码浅谈
引
有这样一句俗语: ”没有前面那个1,后面多少个0都无意义“
正
多项式
先从多项式讲起,一个数值可以表现出多项式的形式,如例1:
27017 = 2 × 1 0 4 + 7 × 1 0 3 + 0 × 1 0 2 + 1 × 1 0 1 + 7 × 1 0 0 27017 = 2 \times 10^4 + 7 \times 10^3 + 0 \times 10^2 + 1 \times 10 ^1 + 7 \times 10^0 27017=2×104+7×103+0×102+1×101+7×100
多项式的数学定义:
a 1 x n − 1 + a 2 x n − 2 + a 3 x n − 3 + … + a n x 0 a_1\large x^{n-1} + a_2\large x^{n-2} + a_3\large x^{n-3} + \ldots + a_n\large x^{0} a1xn−1+a2xn−2+a3xn−3+…+anx0
多项式在计算机程序中的表示:用一个变量表示多项式的基 var base = x \large _{}x x,用一个数组表示系数 var arr = [a1, a2, a3, … , an],数组的长度就是项数 n
任何一个数字都可以用不同 base 的多项式表示,所以一个多项式也可以转换为另一个不同 base 的多项式
对于例1,base = 10
则表现为[2, 7, 0, 1, 7]
Tips: 对于base = 10, arr = [0, 0, 3, 2, 5], 我们可以知道其值为325, 但如果是325, 是无法表现出[0, 0, 3, 2, 5], 也就是说,某些情况下,该运算不具有计算机程序中的可逆性
问题1:给定一个多项式,base已知,系数数组已知,如果要把它转换为另一个base2的多项式,base2 < base,那么base2需要一个多大的数组表示?
高base转低base,项数肯定会增多。首先,假设第一个多项式 base = b1 共 n 项,转换为第二个多项式 base = b2 共 m 项,现在就是要计算 m 的值。
一个多项式 X X X,base = b 1 b_1 b1 有 n n n项,则它的值保持在: b 1 n − 1 < = X < = b 1 n − 1 b_1^{n-1}<=X<=b_1^{n}-1 b1n−1<=X<=b1n−1
想要转化为 base = b 2 b_2 b2,假设有 m m m项,则它的值保持在: b 2 m − 1 < = X ′ < = b 2 m − 1 b_2^{m-1}<=X'<=b_2^{m}-1 b2m−1<=X′<=b2m−1,则可得出如下判断:
{ b 2 m − 1 < = b 1 n − 1 b 2 m > = b 1 n \begin{cases} b_2^{m-1}<=b_1^{n-1}\\ b_2^{m}>=b_1^{n}\\ \end{cases} { b2m−1<=b1n−1b2m>=b1n
化简得到:
{ m < = n l n b 1 l n b 2 ( m 向上取整 ) m > = ( n − 1 ) l n b 1 l n b 2 + 1 ( m 向下取整 ) \begin{cases} m<=n\frac{lnb_1}{lnb_2}(m向上取整)\\ m>=(n-1)\frac{lnb_1}{lnb_2}+1(m向下取整)\\ \end{cases} { m<=nlnb2lnb1(m向上取整)m>=(n−1)lnb2lnb1+1(m向下取整)
这里,我们需要考虑的是 m m m向上取整这个条件。因此,对于给定的多项式(base和n都已知),我们如果要得到base= b 2 b_2 b2对应的多项式表示,则 m m m的值为:
function m(b1, b2, n) {
return Math.ceil(n * Math.log(b1) / Math.log(b2))
}
问题2:给定一个多项式,base已知,系数数组已知,如何用程序转换为另一个已知base2(base2 < base)的多项式?
首先,假设第一个多项式 base = b1 共 n 项,转换为第二个多项式 base = b2 共 m 项,m已经在上一步计算出来了。
第一个多项式可以表示为
( ( ( ( a 1 b 1 + a 2 ) b 1 + a 3 ) b 1 + a 4 ) b 1 + … a n − 1 ) b 1 + a n ((((a_1b_1+a_2)b_1+a_3)b_1+a_4)b1+\ldots a_{n-1})b_1+a_n ((((a1b1+a2)b1+a3)b1+a4)b1+…an−1)b1+an
然后,将 a 1 a_1 a1转化为 b 2 b_2 b2多项式,类似与 a 1 = c 1 × b 2 t − 1 + c 2 × b 2 t − 2 + … + c n × b 2 0 a_1 = c_1 \times b_2^{t-1} + c_2 \times b_2^{t-2} + \ldots + c_n \times b_2^{0} a1=c1×b2t−1+c2×b2t−2+…+cn×b20 得到数组arr
,每一项都小于 b 2 b_2 b2,该多项式的和为 a 1 a_1 a1
操作数组末位 c n c_n cn ( c n × b 1 + a 2 ) ÷ b 2 (c_n \times b_1 + a_2) \div b_2 (cn×b1+a2)÷b2,结果作为新的 a 2 a_2 a2, 余数保留(unshift
)到新数组arr2
中,重复该行为,直到arr
的首位被处理,将余数和结果依次保留(unshift
)到新数组arr2
中。此时,得到了 a 1 b 1 + a 2 a_1b_1+a_2 a1b1+a2的多项式数组
然后如此重复,直到计算完 a n a_n an项
程序如下:
const PolynomialTransformation = (base1, arr1, base2) => {
//先排除开头的0
let start = 0;
for(let i = 0; i < arr1.length; i++){
if(arr1[i] !== 0){
break;
}
else{
start++;
}
}
//全0返回空数组
if(start === arr1.length){
return [];
}
let arr2Length = Math.ceil((arr1.length - start) * (Math.log(base1) / Math.log(base2)));
let arr2 = new Array(arr2Length).fill(0);
let stepLength = arr2.length - 1;
for (let i = 0; i < arr1.length; i++) {
let carry = arr1[i];
let place = arr2.length - 1;
while (true) {
carry += base1 * arr2[place];
// 计算a1的b2多项式
// 取余
arr2[place] = carry % base2;
// 获取进位数
carry = Math.floor(carry / base2);
if (carry === 0 && place <= stepLength){
stepLength = place;
break;
}
place--;
}
}
return arr2;
};
这个函数可以做到多项式在不同进制间的转化
对于一个确定的多项式:
base = 62, arr 为 `(16) [31, 27, 52, 6, 3, 21, 0, 9, 13, 27, 2, 46, 26, 57, 59, 22]
base = 256 arr为 `(12) [78, 34, 113, 96, 17, 249, 156, 67, 183, 15, 179, 84]`
按上述的内容,对于base = 62, arr 的字符串映射为 'vrQ63l09dr2KqVXm'
,欲要转化为256,在此时就已确定了其长度:
Math.ceil(16 * Math.log(62) / Math.log(256)) // 12
假设期望的是14个长度,则无法做到
可以看出,如果base = 62, 则这个函数的逻辑就是Base62编解码的实现细节
如果我们定义自己的map:
// default map
const map = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'
就可以得到自定义的base62了。这个和base62.js中的逻辑类似,它也有自定义字符集的操作
It’s also possible to define a custom character set instead ——原文内容
用
Base62编解码一般用在哪些地方?
Base62编码是由10个数字、26个大写英文字母和26个小写英文字母组成,多用于安全领域和短URL生成。
短网址编码流程:
- 将长地址与一个整数(int64)建立映射(一对多)
- 对上一步的整数进行Base62编码(10进制转62进制)
- 拼接上域名
B站的av,bv码为Base58编码
Base64编码
Base64编码是用64(2的6次方)个ASCII字符来表示256(2的8次方)个ASCII字符,也就是三位二进制数组经过编码后变为四位的ASCII字符显示,长度比原来增加1/3。
Base64 编码是对二进制数据进行编码,表示成文本格式,且只包含 A-Z、a-z、0-9、+、/、=这些字符
原理:把 3 字节的二进制数据按 6bit
一组,用 4 个 int 整数表示,然后查表,把 int 整数用索引对应到字符,得到编码后的字符串。
区别
表格如下:
项 | base62 | base64 |
---|---|---|
是否有进制转化 | 是 | 否 |
是否为流式处理 | 否 | 是 |
是否有header | 否 | 是 |
是否有事实标准 | 否 | 是 |
边栏推荐
猜你喜欢
MySQL压缩包方式安装,傻瓜式教学
MySql 5.7.38 download and installation tutorial, and realize the operation of MySql in Navicat
LeetCode·Daily Question·952. Calculate Maximum Component Size by Common Factor·Union Check
@RequestBody、 @RequestParam 、 @PathVariable 和 @Vaild 注解
系统结构考点之CRAY-1向量处理机
MySql 5.7.38下载安装教程 ,并实现在Navicat操作MySql
系统结构考点之并行主存
PhpMetrics 使用
c语言进阶篇:指针(五)
基于ABP实现DDD--仓储实践
随机推荐
2022.7.30
MYSQL JDBC Book Management System
2022.7.28
2022/07/30 学习笔记 (day20) 面试题积累
cmd(命令行)操作或连接mysql数据库,以及创建数据库与表
mysql去除重复数据
The Road to Ad Monetization for Uni-app Mini Program Apps: Rewarded Video Ads
【导航规划】导航规划背景知识总结
Navigation Bar----Personal Center Dropdown
成功解决ModuleNotFoundError: No module named ‘Image‘
3分钟带你了解微信小程序开发
ValueError: Append mode is not supported with xlsxwriter解决方案
ML's shap: Based on FIFA 2018 Statistics (2018 Russia World Cup) team match star classification prediction data set using RF random forest + calculating SHAP value single-sample force map/dependency c
关于XML的学习(一)
【Untitled】
MySql统计函数COUNT详解
MySql 5.7.38下载安装教程 ,并实现在Navicat操作MySql
解决npm warn config global `--global`, `--local` are deprecated. use `--location=global` instead
ClickHouse删除数据之delete问题详解
MySQL分页查询的5种方法