Perl:标量,数组,哈希

Perl:标量,数组,哈希,第1张

标量是一个简单的数据单元。标量可以是一个整数,浮点数,字符,字符串,段落或者一个完整的网页。

1 数字标量

2 字符串标量

注意单引号和双引号的区别

3 标量运算

4 多行字符串

5 特殊字符

如: __FILE__ , __LINE__ , 和 __PACKAGE__ 分别表示当前执行脚本的文件名,行号,包名。

这些特殊字符是单独的标记,不能写在字符串中,例如:

6 v字符串

一个以v开头,后面跟着一个或多个用句点分隔的整数,会被当作一个字串文本。

当你想为每个字符 直接声明其数字值时,v-字串提供了一种更清晰的构造这类字串的方法,而不像 "\x{1}\x{14}\x{12c}\x{fa0}" 这种不易于理解

Perl数组是一个存储标量值的列表变量,变量可以是不同类型。

数组变量以 @ 开头。访问数组元素使用 $ + 变量名称 + [索引值] 格式来读取

1 创建数组

数组变量以 @ 符号开始,元素放在括号内,也可以以 qw 开始定义数组

@array = (1, 2, 'Hello');

@array = qw/ 这是 一个 数组/;

第二个数组使用 qw// 运算符,它返回字符串列表,数组元素以空格分隔。当然也可以使用多行来定义数组:

@days = qw/google

taobao

runoob/;

也可以按索引来给数组赋值,如下所示:

$array[0] = 'Monday';

$array[6] = 'Sunday';

2 访问数组元素

访问数组元素使用 $ + 变量名称 + [索引值] 格式来读取,实例如下:

数组索引值从 0 开始,即 0 为第一个元素,1 为第二个元素,以此类推。

负数从反向开始读取,-1 为第一个元素, -2 为第二个元素

3 数组序列号

Perl提供了可以按序列输出的数组形式,格式为 起始值 + + 结束值

4 数组大小

数组大小由数组中的标量上下文决定的,数组长度返回的是数组物理大小,而不是元素的个数

5 添加和删除数组元素

Perl提供了一些有用的函数来添加和删除数组元素: push, pop, shift, unshift

实例:

6 切割数组

数组索引需要指定有效的索引值,可以是正数后负数,每个索引值使用逗号隔开。

如果是连续的索引,可以使用 来表示指定范围:

7 替换数组元素

Perl中数组元素替换使用splice()函数,语法格式如下:

splice(@array, offset, length, list)

参数说明:

@array:要替换的数组

offset:起始位置

length:替换的元素个数

list:替换元素列表

实例:

8 将字符串转换为数组

Perl中将字符串转换为数组使用split()函数, 语法格式如下:

split(pattern, expr, limit);

pattern:分隔符,默认为空格。

expr:指定字符串数。

limit:如果指定该参数,则返回该数组的元素个数。

9 将数组转化为字符串

Perl中将数组转换为字符串使用join()函数,语法格式如下:

join(expr, list);

参数说明:

EXPR:连接符。

LIST:列表或数组。

10 数组排序

Perl中数组排序使用sort()函数,语法格式如下:

sort(subrountine, list);

参数说明:

SUBROUTINE:指定规则。

LIST:列表或数组。

实例:

注意:数组排序是根据ASCII数字值来排序。我们在对数组进行排序时,最好先将每个元素转换成小写后再排序。

11 特殊变量:$[

特殊变量 $[ 表示数组的第一索引值,一般都为0, 如果将 $[  设置为1,则数组的第一索引值即为1,第二个为2,以此类推

实例:

一般情况不建议使用特殊变量 $[ ,在新版 Perl 中,该变量已废弃。

12 合并数组

数组的元素是以逗号来分割,我们也可以使用逗号来合并数组,如下:

13 从列表中选择元素

一个列表可以当作一个数组使用,在列表后指定索引值可以读取指定的元素:

哈希是key/value对的集合。 Perl中哈希变量以百分号(%)标记开始。

访问哈希元素格式:${key}

1 创建哈希

一,为每个key设置value

$data{'google'} = 'googlecom';

$data{'w3cschool'} = 'w3cschoolcn';

二,通过列表设置

(1) 列表中第一个元素为key, 第二个元素为value

%data = ('google', 'googlecom', 'w3cschool', 'w3cschoolcn', 'taobao', 'taobaocom');

(2) 也可以使用=>符号来设置key/value

%data = ('google'=>'googlecom', 'w3cschool'=>'w3cschoolcn', 'taobao'=>'taobaocom');

(3) 使用 - 来代替引号

%data = (-google=>'googlecom', -w3cschool=>'w3cschoolcn', -taobao=>'taobaocom');

实例:

2 访问哈希元素

访问哈希元素的格式:${key}

3 读取哈希值

哈希值提取数组 ,语法格式为:@{key1, key2}

4 读取哈希的key和value

读取所有key

可以通过使用 keys 函数读取 哈希所有的键值,语法格式如下:

keys %hash

可以使用 values 函数来读取哈希所有的值,语法格式如下:

values %HASH

5 检测元素是否存在

如果在哈希读取不存在的key/value对,会返回undefined值,且执行时会有警告提醒。为了避免这种情况,可以使用 exists 函数来判断key是否存在,存在的时候读取

6 获取哈希的大小

哈希大小为元素的个数,我们可以通过key或value的所有元素数组,再计算数组元素多少来获取哈希大小

7 哈希中添加或删除元素

添加key/value对可以通过简单的赋值来完成。但是 删除哈希元素需要使用 delete 函数

两个内容相同的对象具有相同的hashcode;反之不成立。

HashMap对象是根据其Key的hashCode来获取对应的Value。

map的实现是数组结合链表。hashcode决定存放位置,两个对象位置一样时比较equals方法。true的话覆盖(同一个对象),false的添加(不是同一个对象)。

散列表(Hash table,也叫哈希表),是根据键(Key)而直接访问在内存存储位置的数据结构。也就是说,它通过计算一个关于键值的函数,将所需查询的数据映射到表中一个位置来访问记录,这加快了查找速度。这个映射函数称做散列函数,存放记录的数组称做散列表。

通过某种转换关系,使关键字适度的分散到指定大小的的顺序结构中,越分散,则以后查找的时间复杂度越小,空间复杂度越高。

Hash是一种典型以空间换时间的算法,比如原来一个长度为100的数组,对其查找,只需要遍历且匹配相应记录即可,从空间复杂度上来看,假如数组存储的是byte类型数据,那么该数组占用100byte空间。现在我们采用Hash算法,我们前面说的Hash必须有一个规则,约束键与存储位置的关系,那么就需要一个固定长度的hash表,此时,仍然是100byte的数组,假设我们需要的100byte用来记录键与位置的关系,那么总的空间为200byte,而且用于记录规则的表大小会根据规则,大小可能是不定的。

通过哈希函数,我们可以将键转换为数组的索引(0-M-1),但是对于两个或者多个键具有相同索引值的情况,我们需要有一种方法来处理这种冲突。

一种比较直接的办法就是,将大小为M 的数组的每一个元素指向一个链表,链表中的每一个节点都存储散列值为该索引的键值对,这就是拉链法。下图很清楚的描述了什么是拉链法。

“John Smith”和“Sandra Dee” 通过哈希函数都指向了152 这个索引,该索引又指向了一个链表, 在链表中依次存储了这两个字符串。

单独链表法:将散列到同一个存储位置的所有元素保存在一个链表中(聚集),该方法的基本思想就是选择足够大的M,使得所有的链表都尽可能的短小,以保证查找的效率。当链表过长、大量的键都会映射到相同的索引上,哈希表的顺序查找会转变为链表的查找,查找时间将会变大。对于开放寻址会造成性能的灾难性损失。

实现基于拉链表的散列表,目标是选择适当的数组大小M,使得既不会因为空链表而浪费内存空间,也不会因为链表太而在查找上浪费太多时间。拉链表的优点在于,这种数组大小M的选择不是关键性的,如果存入的键多于预期,那么查找的时间只会比选择更大的数组稍长。另外,我们也可以使用更高效的结构来代替链表存储。如果存入的键少于预期,索然有些浪费空间,但是查找速度就会很快。所以当内存不紧张时,我们可以选择足够大的M,可以使得查找时间变为常数,如果内存紧张时,选择尽量大的M仍能够将性能提高M倍。

线性探测法是开放寻址法解决哈希冲突的一种方法,基本原理为,使用大小为M的数组来保存N个键值对,其中M>N,我们需要使用数组中的空位解决碰撞冲突。如下图所示:

对照前面的拉链法,在该图中,“Ted Baker” 是有唯一的哈希值153的,但是由于153被“Sandra Dee”占用了。而原先“Snadra Dee”和“John Smith”的哈希值都是152的,但是在对“Sandra Dee”进行哈希的时候发现152已经被占用了,所以往下找发现153没有被占用,所以索引加1 把“Sandra Dee”存放在没有被占用的153上,然后想把“Ted Baker”哈希到153上,发现已经被占用了,所以往下找,发现154没有被占用,所以值存到了154上。

单纯论查找复杂度:对于无冲突的Hash表而言,查找复杂度为O(1)。

原文: 哈希查找 - 卖贾笔的小男孩 - 博客园 (cnblogscom)

比特币的挖矿难度可以使用Target Threshold,nBits或Difficulty表示,它们互相等价:

这三个值的转化关系可以采用下面的实例来说明:

首先获取哈希值为 000000000003ba27aa200b1cecaad478d2b00432346c3f1f3986da1afd33e506 的区块原生十六进制信息如下:

区块中nBits采用小端格式表示,解析区块信息,得到nBits字段值为0x4c86041b。因此转化为大端格式为0x1B04864C,这个值是Target Threshold的压缩格式表示,可以将它转化成256位的Target Threshold值:

开头的一个字节为指数,后面三个字节为系数,则:

计算出Target Threshold值为 0x000000000004864c000000000000000000000000000000000000000000000000 。

再计算Difficulty的值,它有两个值,计算公式分别为:

由此可以使用 Python 计算出bdiff的值:

因此,得到在比特币客户端中的difficulty值bdiff为14484162361225399。

为了检验上述结果,可以在比特币核心客户端中使用 getblock "000000000003ba27aa200b1cecaad478d2b00432346c3f1f3986da1afd33e506" 命令得到该区块的json格式信息:

最终,可以发现该区块的bits和difficulty字段信息与上面分析计算的相关结果一致。

nBits的大端格式表示法中,其系数最大为0x7fffff,这是因为Target Threshold数据类型是无符号整型,而它继承自有符号数据类,则在实际中Target Threshold系数的最高位有可能是1,这可能会被解析成一个负数。则在挖矿过程中难度值永远无法小于一个负数。因此,为了解决这个问题,比特币核心在生成nBits值时需要首先检查一下生成的nBits是否会被解析为一个负数。如果是,首先在系数开头补8位0,即除以256,然后指数再加上1。这样由nBits转化为Target Threshold过程中转化公式就与普通值相同了,即指数位都是减去3,转化过程上面已经提到。

举个例子说明:

哈希值为 00000000d1145790a8694403d4063f323d499e655c83426834d4ce2f8dd4a2ee 的区块信息如下:

发现bdiff值为1,则利用bdiff与Target Threshold关系可以计算出:

将Target Threshold值 0x00000000FFFF0000000000000000000000000000000000000000000000000000 转化为nBits的过程中可以发现其系数为0xffff00,指数为0x1c,这样:

然而由于系数最高位为1,则如果这样表示的话就可能将Target Threshold解析为负数。因此,我们将系数除以256,指数加上1,得到系数为0x00ffff,指数为0x1d。这样:

最终,nBits值为0x1d00ffff(大端表示),与json格式信息一致。

因为所有的哈希函数都接收类型为 Byte() 的输入,因此可能需要将初始数据转换成一个字节数组才能够为它产生哈希值。欲为一个字符串值建立一个哈希值,请依下列步骤进行:1、使用Using语句导入System、SystemSecurity、SystemSecurityCryptographic与SystemText命名空间,这样一来,您才不需要于程序代码中编写一长串的完整名称:using SystemDrawing;using SystemText;using SystemWindowsForms;using SystemSecurityCryptography;2、声明一个字符串变量来持有您的初始数据,并声明两个字节数组(未定义大小)来持有初始字节与所产生出的哈希值:string sSourceData;byte[] tmpSource;byte[] tmpHash;3、使用 GetBytes() 方法(它是SystemTextASCIIEncoding类的一部分)将您的初始字符串转换至一个字节数组中:sSourceData = "MySourceData";// 根据初始数据来建立一个字节数组tmpSource = ASCIIEncodingASCIIGetBytes(sSourceData);4、通过调用MD5CryptoServiceProvider类的实例的ComputeHash方法来为您的初始数据计算出MD5哈希值。请注意,欲计算出另外一个哈希值,您必须建立该类的另外一个实例。// 根据初始数据计算出哈希值tmpHash = new MD5CryptoServiceProvider()ComputeHash(tmpSource);5、tmpHash字节数组现在会获取您初始数据的哈希值(128位值=16字节)。将此显示或储存成一个十六进制字符串通常会非常有用,下列程序代码即是进行此项处理:lblHashResultText = sSourceData + "\n" + ByteArrayToString(tmpHash) + "\n";private string ByteArrayToString(byte[] arrInput){StringBuilder sOutput = new StringBuilder(arrInputLength);for (int i = 0; i < arrInputLength; i++)return sOutputToString();}6、通过上述程序代码,您便能够为初始数据产生出哈希值并以一个十六进制字符串来表示。接下来,我们要继续说明如何比较两个哈希值。为初始数据建立哈希值的目的之一,就是要提供一种方式来检查数据是否被更改过,或是不通过实际的值来比较两个值。不论是哪一种情况,您都需要比较两个哈希值。然而,如果两个哈希值皆已储存成十六进制字符串,则比较哈希值的 *** 作将会更加简易。当然,也有可能两个哈希值都是以字节数组的形式存在。后续步骤的程序代码将延续先前步骤的程序代码,以便示范如何比较两个字节数组。7、请在建立一个十六进制字符串的地方,紧接着根据新的初始数据建立一个新的哈希值:sSourceData = "NotMySourceData";tmpSource = ASCIIEncodingASCIIGetBytes(sSourceData);byte[] tmpNewHash;bool bEqual = false;tmpNewHash = new MD5CryptoServiceProvider()ComputeHash(tmpSource);8、比较两个字节数组最直接了当的方式就是通过循环依序处理数组,以便一一比较两数组中的每一个元素。如果有任何元素不相同,或是两数组的大小不相同,则表示两值并不相等:if(tmpNewHashLength == tmpHashLength){int i = 0;while((i < tmpNewHashLength) & & (tmpNewHash[i] == tmpHash[i])){i += 1;} if(i == tmpNewHashLength){bEqual = true;}}if (bEqual){lblHashResultText += "这两个哈希值是相同的";}else{lblHashResultText += "这两个哈希值并不相同";}9、保存与运行您的项目,以便查看根据第一个哈希值所建立的十六进制字符串,并确认新的哈希值是否与初始的相同。

看了下那个hashcat-gui 已经是很老的东西了,2012325 最后更新出错的话截个图来让大家帮你看看oclHashcat-plus 很久以前叫这个名字,现在都合并到oclHashcat了。你说它是替代版本也没错。他们的区别就是hashcat只支持CPUPJ(多线程) oclHashcat支持GPUPJ运行EXE文件命令行一闪而过你要到命令行下运行,就像这样的格式 c:\testexe 这种或者你到软件目录下,新建一个abat的批处理文件,里面就写cmd,后缀一定要是bat,双击执行就出来cmd,在里面执行软件不清楚EWSA 能否支持R9 270X希望能够帮到你

以上就是关于Perl:标量,数组,哈希全部的内容,包括:Perl:标量,数组,哈希、java哈希值、哈希查找算法等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/web/9286526.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-04-26
下一篇 2023-04-26

发表评论

登录后才能评论

评论列表(0条)

保存