常见的编码总结(二)

 

一.HTML的字符集

1.字符集出现的原因

字符集是用来统一传输过程中信息的一致性,就如同,两个来自不同国家的人的对话一样。

一个俄罗斯人和一个中国人,两者都会英语和本国的语言。

中国人在大脑中构思好"你好啊"这句话,然后自己翻译成英语"hello"。

俄罗斯收到"hello",后再在大脑中翻译成俄语中"你好“的意思。这样一次简单的对话,才能成立,否则,只能是鸡同鸭讲。

同理我们在服务器和客户两者之间,也需要统一的"语言",否则也会出现理解不了的情况。

2.字符实体(Character entity)

在编写html中,如果我们要显示一些特殊字符,比如说:">"、"<"等,因为浏览器会将其误认为是标签,进而不能正确的显示

如,我们要在页面中显示"<a"

<!DOCTYPE html>
<html lang="en">
<head>
	<meta charset="UTF-8">
	<title>Document</title>
</head>
<body>
	<p>是否能正确显示小于号和a标签呢?</p>
	<a
</body>
</html>

现在打开火狐

下图是打开后的页面,很明显,未能正确的显示"<a",同时要注意,在查看元素中,浏览器会自动修正一些问题,如自动将a

标签闭合,并添加了</a>标签。

 

打开源代码,

还是原来的代码。

接下来是chrome浏览器,也没能正确显示

然后是,ie浏览器 

 此时,就需要字符实体来发挥作用了

只需要用"&lt;"或者"&#60;"或者"&#x03C"即可

修改代码为:

<!DOCTYPE html>
<html lang="en">
<head>
	<meta charset="UTF-8">
	<title>Document</title>
</head>
<body>
	<p>是否能正确显示小于号和a标签呢?</p>
	&lt;a
	&#60;a
	&#x03C;a 
</body>
</html>

打开页面

查看源代码

 3.字符实体的格式

在html中字符实体的格式有两种:

类型一:

           &#entity_number;

           其中,entity_number,可以是十进制或者十六进制,如下

           &#60;

           &#x03C;

类型二:

           &entity_name;

                   

           &lt;

以上在html中都可以表示小于号。

注意:类型一中的entity_number的数值(十进制)与该字符的ascii值一致。

但是,我们知道ascii使用7个比特来表示的,所以最多只能有128个。但是能够在页面中显示的字符可远远超过128个,所以,还可以用较大的数来描述。

如 "∀",可以用"&#8706;"或者"&part;"来表示。

二、JS的编码总结

以下内容应用自《web安全功放:渗透测试指南》

js提供了四种字符编码的策略,如下所示。

  • 三位八进制数字,如果个数不够,在前面补0,例如"e"的编码为"\145"
  • 两位十六进制数字,如果个数不够,在前面补0,例如"e"的编码为"\x65"
  • 四位十六进制数字,如果个数不够,在前面补0,例如"e"的编码为"\u0065"
  • 对于一些控制字符,使用特殊的C类型的转义风格(例如\n和\r)

如,<script>eval("alert(1)")</script>,我们可以有一下三种表达:

八进制:<script>eval("\141\154\145\162\164\50\61\51")</script>

16进制:<script>eval("\x61\x6c\x65\x72\x74\x28\x31\x29")</script>

16进制:<script>eval("\u61\u6c\u65\u72\u74\u28\u31\u29")</script>

前面两个都能正常弹出警告框,为什么第三个不行呢?

在firefox中打开改页面,后发现:

SyntaxError: malformed Unicode character escape sequence,意思是unicode中的字符实体顺序出了问题。

查阅资料后发现,原因是这样的

js中可以直接通过eval执行的字符串有八进制和16进制两种编码方式,其中八进制用\56,十六进制用\x5c的格式。

需要注意的是这两种字符表示方式不能够直接给多字节字符编码(如汉字、韩文),如果代码中应用了汉字并且需要进行进制编码,那么只能进行十六进制Unicode编码,其表示形式为:\u4ee3\u7801("代码"二字的十六进制编码)。

所以,上述第三种方法在这里不能正确的执行,但是我们可以换一种其他的表达方式:

<a href="javascript:\u0061\u006c\u0065\u0072\u0074("您好")">test</a>

将其放在html中,执行下

点击test,后弹窗

上述\u0061\u006c\u0065\u0072\u0074,是对"alert"这个字符串进行的js编码,记住在js解析器中,必须是四位16进制,否则不能正确执行。

那现在能不能将<a href="javascript:alert(1) ">中的"alert(1)",进行16进制的编码呢?尝试下

 

打开页面,点击test3没有任何反应,问题出来了;

看一下,这个解释

https://security.yirendai.com/news/share/26

里面说了,"alert"是一个有效的标识名称,它可以被正常解析。但是像圆括号、双引号、单引号等等这些控制字符,在进行javascript解析的时候仅会被解码位字符串文本或者上面讲的标识符名称,但是在该过程中这些特殊字符已经没有控制字符的作用,所以无法闭合,因此执行失败。

三、URL编码

 

关于为什么要进行url编码,看看这篇文章?

https://www.cnblogs.com/jerrysion/p/5522673.html

URL编码的格式为:

URL编码通常也被称为百分号编码,是因为它的编码方式非常简单,使用%百分号加上两位的字符(16进制格式)。

这两位字符是依据ascii来决定的,

比如,英文单引号的ascii值为:27(16进制格式)

经过URL编码后为,%27 

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值