枚举变量

base = 36  tmin = 1 tmax = 26(阈值) skew = 38 damp = 70 initial_bias = 72 initial_n =128(0x80 ) delimiter = 0x2d(分隔符 -)

basic (cp)  判断是不是基本字符,即ASCII以内字符

delim(cp)  判断是不是 “-”符号

decode_digit(cp)将punycode 36进制数转换成整数

encode_digit (d,flag) 将字符转换成 0..25代表字面,26..35表示数字

maxint = -1

adapt (delta,numpoints,firsttime)   delta 是增量,numpoints是当前所有已编码的码位数量

可变长整数:

传统的可变长整数,如,100,2983等等等,但是,这些可变长整数一旦连接在一起,1002983,则不能知道两个整数的界限了,于是,要构造一个新的可变长整数格式:

每一位有一个阈值,t(j)

恰好只有一个权重最大的digit_j<t(j),从而可以区分各个数。

如,734251…..    对应的阈值为,2,3,5,5,5,5….

因为7>2,3=3,2<5,所以,2就是那个权重最大的digit,因此,734是一个数,类推,只,251是一个数。

这里,可以将734,251理解成punycode编码后的值,只需要将其解码:各位数,乘以各自权重求和,就可以得到对应的Unicode,从而得到对应的汉子。

权重公式如下:

W(0)  =  1

W (j)  = w( j-1 ) * (base  -  t(j-1) ) 当j>0时

阈值公式如下:

t(j)  =  base * ( j+1 ) – bias

如果计算出t(j) 小于tmin,则t(j) = tmin, 大于tmax 则 t(j) = tmax

Bias 的值是根据贝叶斯调制而得:

1.  为了避免下步操作数据溢出,堆会按照比例缩小

第一次缩小,delta= delta/damp

第二次及以后,delta= delta/2

2.  堆的增加补偿了下个堆会被放入更长的字符串里:

Delta = delta + (delta/numpoints)

3.堆不断减小,直到落入界限值

for (k = 0; delta > ((base - tmin) * tmax) / 2; k += base)

{

delta /= base - tmin;

}

4.得到bias 的值

k + (base - tmin + 1) * delta / (delta + skew);

相反的过程,就是编码过程,编码过程,就是将Unicode差值,编码成可变长整数的过程,而这个可变长整数的取值范围是a~z,0~9的36进制。

编码步骤:

1.       基础码分离:先扫描全部输入,将ASCII部分,按照原来的次序排在前面的部分,插入‘-’用以分离

2.       把字按Unicode大小递增排序

3.       计算相邻Unicode码差值

4.       差值乘以初始码位置序号+排序后序号,得到增量

5.       对得到增量编码成base-36编码

6.       处理所有增量

如“中国互联网网络中心!”

变量初始值

n=initial_n = 128

delta = 0

bias = initial_bias = 72

h = out(out为输出字符串当前输出的位置,由于字符串中有!,所以,目前的h=out= 1)

对应的Unicode 为

20013  22269  20114 32852 32593 32593 32476 20013 24515 33

除去对‘!’处理,现在看对中文编码部分

参数m记录当前Unicode最小值,n代表上一个最小的Unicode值,因为‘ 国’的Unicode编码值大于‘中’字,所以,先对‘中’进行处理 (下面过程不考虑报错情况)

所以,当前

m= 20013   n = 128

对应的delta = (m-n)*(h+1) = 39770

这个过程之后,n=m,为下一次计算差值做好准备。

Punycode所要编码的项目,则就是这个delta值,即,后一个字符与前一个字符的Unicode数值之差。

接下来是编码过程,编码过程是将39770由地位向高位一位一位的编码成一个可变长整数的过程。

先以十进制为例,如816这个数,要求出各位数值,则得从低位开始计算,816%10 = 6 则得出,低位的第一位是6,然后,816/10 =81, 81%10=1,则其次低位为1,再之,81/10=8, 8%10 = 8 ,则最高位为8

下面的代码则是针对base_36 做相同的操作

for (q = delta, k = base;; k += base)

{

if (out >= max_out)

return punycode_big_output;

t = k <= bias /* + tmin */ ? tmin :         /* +tmin not needed */

k >= bias + tmax ? tmax : k - bias;

if (q < t)

break;

output[out++] = encode_digit (t + (q - t) % (base - t), 0);

q = (q - t) / (base - t);

}

output[out++] = encode_digit (q, case_flags && case_flags[j]);

bias = adapt (delta, h + 1, h == b);

首先计算低位的阈值,阈值的公式是

t = base*(j+1)-bias

而如果t大于tmax,则t=tmax,反之,t= tmin

j表示当前的位数,从0增长

bias,初始值为initial_bias = 72

第一次,t + (q - t) % (base - t) 可以得出 最低位 为 10 经过编码成base_36 对应字符为 k

只要q>t ,则表明,仍然是 39770这个数在编码

继而得到,其他位为 16 , 32  , 0

对应编码为  q  , 6   ,a

所以,第一个字的编码 为 kq6a

以此类图,可以得到全部的编码信息。

可以验证,对于 39770这个数

权值

因为

W(0)  = 1

W(j)  = w(j-1)*(base – t (j-1) )

w(0) =1

w (1)= w (0) * (36 - 1) = 35

w  (2)  = w(1)*(36-1) =352

w (3)  = w (2) * (36 - 1)  = 353

而,39770 = 0 * 353 + 32*352 + 16*35 +10 * 1

punycode编码相关推荐

  1. 手机号码转码_中文域名转码,中文域名PunyCode编码转换,中文域名在线转码工具,Punycode编码在线转换工具...

    中文域名分为两类: 1.一类是域名后缀为英文字母的国际中文域名和别国中文域名,比如:中文.com,中文.net,中文.biz,中文.cc,中文.hk,中文.tm,中文.tv,中文.tw: 2.一类是域 ...

  2. php中文域名转码,中文域名的punycode编码与其python实现

    Punycode是一个根据RFC 3492标准而制定的编码系统,主要用於把域名从地方语言所采用的Unicode编码转换成为可用於DNS系统的编码.Punycode可以防止所谓的IDN欺骗. 早期的DN ...

  3. punycode转码以及UniCode编码表参考文章

    Punycode是什么? Punycode是一个根据RFC 3492标准而制定的编码系统,主要用於把域名从地方语言所采用的Unicode编码转换成为可用於DNS系统的编码.Punycode可以防止ID ...

  4. Nginx配置中文域名

    今天碰到一个好玩的问题,还以为是nginx的缓存,各种清理就差把nginx卸载了,后来想想不对应该是中文域名的问题,对中文进行编码,搞定,如下: ... server {listen 80;serve ...

  5. linux dns中文域名,Nginx 中文域名配置详解及实现

    Nginx中文域名配置 Nginx虚拟主机上绑定一个带中文域名,比如linuxeye.中国,浏览器不能跳转. why? 因为操作系统的核心都是英文组成,DNS服务器的解析也是由英文代码交换,所以DNS ...

  6. Nginx中如何配置中文域名?

    大家好,我是雄雄,欢迎关注公众号[雄雄的小课堂]. 最近我的个人站上线了,一直在优化中,目前优化最多的就是后台,将主页面的色彩重新搭配了下,稍微好看点儿了,以下是后台界面: 前台界面如下: 现在里面的 ...

  7. linux dns中文域名,Linux 搭建中文域名的DNS服务器

    配置之前先来解释一下中文域名是如何工作的: 当我们在浏览器上输入 朝阳.北京.中国 这个域名的时候 浏览器会把中文域名翻译成Punycode编码然后再 传送给DNS服务器解析,例如 朝阳.北京.中国 ...

  8. 【script】python 中文汉字与url的转换

    punycode 编码(推荐) punycode 编码又称 域名代码,是实现 中文汉字转英文字母 的一种编码方式 中文汉字 转 url import reurl = 'www.示例.com' # 正则 ...

  9. 浏览器从输入到输出的过程与原理一

    1. 浏览器与触屏 1.1 用户输入[input] USB键盘 键盘的USB元件通过计算机上的USB接口与USB控制器相连接,USB接口中的第一号针为它提供了5V的电压 键码值存储在键盘内部电路一个叫 ...

最新文章

  1. Iptables防火墙配置详解
  2. designer一直未响应 qt_未雨绸缪及时清淤 曾是内涝重灾区 这次涵洞未积水
  3. java 文件流的帮助类
  4. java基础(七)--- set
  5. 为啥用计算机分析模拟,模拟电路的计算机分析与设计——Pspice程序应用
  6. a 机械硬盘损坏,如何恢复数据
  7. AutoHotKey完成ass字幕文件字幕偏移时间修改
  8. 阿里云 mysql 100_【故障公告】阿里云 RDS 数据库服务器 CPU 100% 造成全站故障
  9. 你所不知道的BGP知识,Peering 和IP-Transit.
  10. python求15 17 23 65 97的因数_Python学习记录15
  11. html中使用img标签图片无法正常显示
  12. php guzzle并发,使用Guzzle并发请求接口
  13. JS day_08(5.17)String 、 Math
  14. 香港电视剧的配音怎么都是一个腔调的呢?
  15. 如何使用a股量化交易api接口?
  16. 撤县设区,就能过城里人的生活了?
  17. 记录有关Https、443、SSL、百度地图、云服务器、网易有数BI 等相关知识
  18. 智能肛珠作弊案反转:19岁小将告世界冠军诽谤索赔7亿
  19. 【汇正财经】有色:全球钼价轮番拉涨,小市场或有大行情
  20. 对日软件外包是干什么?

热门文章

  1. Unity零基础到入门 ☀️| 近万字教程 对 Unity 中的 动画系统基础 全面解析+实战演练,你确定要错过吗?
  2. 三星mzvlb1t0hblr是什么固态_固态硬盘跑分速度天梯图/天梯表,最全搜集。
  3. 使用Termux把Android手机变成SSH服务器
  4. PIPI1003: 最少钱币数c++
  5. Redmi K20 安卓9跨版本刷第三方ROM
  6. Proteus仿真——用两片74HC148及少量逻辑门构成16线--4线优先级编译器
  7. 2017字节跳动秋招编程题-头条校招
  8. 全球十大航天发射基地
  9. python3.7 如何去掉字符串\xa0/\xa0
  10. Python之基础详解(八):必备,以制作交易收盘价走趋图为例,来可视化处理json格式的文件