發新話題

網路管理語言 Perl 入門與實作

4.1.18 亂數
rand 函式提供亂數機制,如下:
引用:
語法:

rand 某數  (傳回介於 0 ~ 某數之間的正數)



rand       (傳回 0 ~ 1 之間的正數)
用例:
引用:
#! /usr/bin/perl

$num1 = rand 100; # 傳回 0 到 100 之間的隨機正數。

$num2 = rand; # 傳回 0 ~ 1 之間的隨機正數

print $num1,"\n", $num2, "\n";

# 可能輸出:

41.672293825923
0.216416427956091
我們經常需要的是傳回整數,int 這個函式可以幫我們做到:
引用:
#! /usr/bin/perl

while (1) {
        $num = int(rand 42) + 1;
        print $num, "\n";
        sleep 1;
}

# 傳回 1 ~ 42 隨機一個正整數。若欲停止,請按 Ctrl + C 鍵。
# 可能輸出:

23
35
13
29
27
21
25
1
40
31
27
18
16
另,為了使每次執行亂數程式時,都能有不同的結果,Perl 另外提供亂數種子 srand 這個函式。

註:新版的 Perl 已改善此點,不必使用 srand,也可使每次亂數結果不同。

用例:
引用:
srand



srand 任意數字

例 srand 5;

用例:

#! /usr/bin/perl

# 設亂數種子,以當時的時間做為亂數種子
srand time();

while (1) {
        $num = int(rand 42) + 1;
        print $num, "\n";
        sleep 1;
}

TOP

4.1.19 時間的處理
如何取得現在的日期時間呢?

利用 localtime 函式,localtime 會傳回一個包含主機時間(年月日時分秒)的陣列,用法如下:
引用:
#! /usr/bin/perl

# 取得秒, 分, 時, 日, 月, 年
($sec,$min,$hour,$day,$mon,$year)=localtime(time);

# 月比實際少一, 所以加 1
$mon++;

# 判斷是否為個位數, 若是則在前面補 0
if (length ($mon) == 1) {$mon = '0'.$mon;}
if (length ($day) == 1) {$day = '0'.$day;}
if (length ($hour) == 1) {$hour = '0'.$hour;}
if (length ($min) == 1) {$min = '0'.$min;}
if (length ($sec) == 1) {$sec = '0'.$sec;}

# 年比實際西元年少 1900, 所以加上 1900
$year+=1900;

# 組合成完整的時間
$alltime="$year/$mon/$day,$hourminsec";

print $alltime, "\n\n";

TOP

4.1.20 編碼加密處理
如何把某一字串做編碼加密呢?

這裡簡單介紹傳統的加密函式 crypt,用法如下:
引用:
語法:

crypt 欲加密的字串,salt;

注意:crypt 只會取用 salt 字串中前二個字元,超過的予以忽略。

例:

#! /usr/bin/perl

print "請輸入您要加密的字串?";
chomp($str=<STDIN>);
print "請輸入任意二個字元?";
chomp($salt=<STDIN>);

$pwd=crypt $str, $salt;

print "$str 的加密結果:$pwd\n\n";

# 可能輸出結果:

請輸入您要加密的字串?larrywall
請輸入任意二個字元?9m
larrywall 的加密結果:9mpSIssRh4Lbs
crypt 可以運用到 /etc/passwd (非 shadow 型) 上,假定 pass 是 /etc/passwd 上已加密過的密碼字串,則以下例子可以比對:使用者輸入的密碼,與 /etc/passwd 中他自己的密碼,是否相符?
引用:
chomp($keyin_pwd=<STDIN>);

# $pass 代表由 /etc/passwd 取得的加密密碼
if ((crypt $keyin_pwd, $pass) eq $pass) {
        print "密碼正確!\n";
}
Perl 的 crypt,採用 DES(Data Encryption Standard) 修改過的版本,它是一種單向加密。換言之,您無法由加密後的密文,來反推其原來的明文為何?不過,這並不表示它不能被破解。(常見的攻擊方法之一:字典攻擊法。)

TOP

4.2 陣列
談 Perl 的陣列之前,應先來瞭解何謂串列(list)?

TOP

4.2.1 串列
串列是小括號()內,由一串純量組成(0 個元素以上),彼此以逗點分開。比如:
引用:
(1, 2, 3, 4) 這是有 4 個數值元素的串列

("John", 5, 6, "ijk", 7) 這是 5 個元素,字串及數值純量混合的串列。

若元素是連續的,可以使用 "範圍算符" .. 來表示區間。

(1..1000) 表示 1 到 1000 所組成的串列。

(5..10)

(5.1..10.7) 同上,它會把小數去掉。

(1, 3, 5..8, 9, 10) 同 (1, 3, 5, 6, 7, 8, 9, 10)

("Mmm", "NNN", "Jjj", "Kkk", "Xxx")

串列也可以是空的:

() 空串列


變動形的串列:

$l=10;
$t=20;

($l, $t) 此串列的大小由 $l, $t 決定
像 ("Mmm", "NNN", "Jjj", "Kkk", "Xxx") 這種串列要鍵入那麼多雙引號,挺累人的,您也可以用 qw 算符來簡化它(別忘了 Perl 是懶惰程式設計師的最愛):
引用:
("Mmm", "NNN", "Jjj", "Kkk", "Xxx")

同於

qw( Mmm NNN Jjj Kkk Xxx )
換言之,qw 是將串列元素加上引號(quoted words,因此簡稱為 qw),並且以空白分隔。除此之外,您也不一定要用小括號,您可用任何符號做為起始及結束符號:
引用:
qw/ Mmm NNN Jjj Kkk Xxx /

qw! Mmm NNN Jjj Kkk Xxx !

qw# Mmm NNN Jjj Kkk Xxx #

qw{ Mmm NNN Jjj Kkk Xxx }

qw< Mmm NNN Jjj Kkk Xxx >

qw[ Mmm NNN Jjj Kkk Xxx ]

以上均同於:("Mmm", "NNN", "Jjj", "Kkk", "Xxx")
串列可用來快速交換變數內容,不需要中間暫存變數:
引用:
傳統交換變數內容之作法如下:

# 把 $a 先放入 暫存變數 $tmp 中
$tmp = $a;

# 把 $b 放入 $a 中
$a = $b;

# 把 $a 值放入 $b 中
$b = $tmp;


但使用串列,就不必再用中間暫存變數了! 如下所示:

# 以下將 $a、$b 兩變數內容交換
($a, $b) = ($b, $a);


# 以下將 $b 給 $a,$c 給 $b,$a 給 $c,形成輪動的效果
($a, $b, $c) = ($b, $c, $a);

TOP

4.2.2 產生陣列
有了串列的預備知識之後,接著我們來看陣列如何產生?

Perl 的陣列,以 @ 加上變數名稱來表示,比如:@oklist,它的元素可由 index 索引逐一取得,第一個 index 值由 0 開始,最後一個 index 值由 $#oklist 來表示。陣列的第一個元素為 $oklist[0],第二個元素為 $oklist[1],第三個元素為 $oklist[2],其它依此類推,最後一個元素為 $oklist[$#oklist]
引用:
@oklist=(1, 2, 4, 6);

@oklist 陣列共有 4 個元素,分別是 $oklist[0], $oklist[1], $oklist[2], $oklist[3]

$#oklist 值為 3

最後一個元素可表示成 $oklist[$#oklist],其值為 6

@tiny=(); # 空陣列


#! /usr/bin/perl

@a=(2, 4, 6);
@b=(1, 3, 5);
@c=qw(a b c);

# 那麼:

@total=(@a, @b, @c); # 同於 (2, 4, 6, 1, 3, 5, "a", "b", "c");

# 可以把陣列一次印出來
print @total;

# 結果:246135abc
在上述範例中,我們把陣列一次印出來,可是所有元素全接在一起了,這有時並不是我們想要的,通常我們希望能在元素之間加入某些分隔符號,比如 "," 逗點,那麼如何做呢? join 這個函式可以幫我們做到這一點,示範如下:
引用:
#! /usr/bin/perl

@a=(2, 4, 6);
@b=(1, 3, 5);
@c=qw(a b c);

# 那麼:

@total=(@a, @b, @c); # 同於 (2, 4, 6, 1, 3, 5, "a", "b", "c");

$result = join ',' , @total;

print $result;

# 結果:2,4,6,1,3,5,a,b,c
上式中,join 函式的作用對象是陣列,語法是:join 表示式, 陣列

因為我們希望 @total 的元素用 "," 號分開,且把結果(是一個字串)放入 $result 中,因此,使用 join ',' , @total;

您可以任意變換您要分隔的符號。

再者,有時我們希望上述的過程可逆,也就是說:把 $result 還原成 @total (2,4,6,1,3,5,a,b,c 變成 246135abc),那麼要怎麼做呢? split 這個函式可以幫我們的忙:
引用:
#! /usr/bin/perl

$result="2,4,6,1,3,5,a,b,c";

@total = split(/,/, $result);

$i=0;
while ($i <= $#total) {
        print '$total[' . $i . '] ===> ' . $total[$i] . "\n";
        $i++;
}

# 輸出:

$total[0] ===> 2
$total[1] ===> 4
$total[2] ===> 6
$total[3] ===> 1
$total[4] ===> 3
$total[5] ===> 5
$total[6] ===> a
$total[7] ===> b
$total[8] ===> c
上式,在 split 中指明分隔符號為 ",",它可以把純量字串 "分割" 成為陣列,然後存放在 @total 中。

TOP

4.2.3 走過每一個陣列元素
這個意思是說,要將某一陣列的每一個元素取出來看看。列舉以下二種作法:

利用 for
引用:
#! /usr/bin/perl

@total=(2, 4, 6, 1, 3, 5, "a", "b", "c");

# 陣列 index 由 0 開始,一直到最後一元素的 index:$#total (即 8)
for ($i=0; $i<=$#total; $i++) {
        $j=$i+1;
        print "第 $j 個元素是:$total[$i]\n";
}
利用 foreach
引用:
#! /usr/bin/perl

@total=(2, 4, 6, 1, 3, 5, "a", "b", "c");

# 陣列 index 由 0 開始,一直到最後一元素的 index:$#total (即 8)
$j=1;
foreach $item (@total) {
        print "第 $j 個元素是:$item\n";
        $j++;
}

TOP

4.2.4 陣列的操作
陣列主要有四個操作

1.pop:由陣列尾端,取出最後一個元素

2.push:由陣列尾端,置入一個元素,形成最後的元素

3.shift:由陣列頭部,取出第一個元素

4.unshift:由陣列頭部,置入一個元素,變成第一個元素

以下依序說明之。

TOP

4.2.5 pop
由陣列尾端,取出最後一個元素:
引用:
#! /usr/bin/perl

@total=(2, 4, 6, 1, 3, 5, "a", "b", "c");

$flast=pop @total;

print "$flast\n"; # 應得到 c

print @total;

# 此時 @total 只剩下 (2, 4, 6, 1, 3, 5, "a", "b");

TOP

4.2.6 push
¥°}¦C§ÝAmJ@­¯G
引用:
#! /usr/bin/perl

@total=(2, 4, 6, 1, 3, 5, "a", "b", "c");

$f2="d";

push @total, $f2;

print @total;
# ¦¹ @total ³¬° (2, 4, 6, 1, 3, 5, "a", "b", "c", "d");
]¥i¥HmJ¥t@­°}¦CG
引用:
#! /usr/bin/perl

@total=(2, 4, 6, 1, 3, 5, "a", "b", "c");

@t2=qw( John Marry Kenny );

push @total, @t2;

print @total;
# ¦¹ @total ³¬° (2, 4, 6, 1, 3, 5, "a", "b", "c", "John", "Marry", "Kenny");

TOP

發新話題

本站所有圖文均屬網友發表,僅代表作者的觀點與本站無關,如有侵權請通知版主會盡快刪除。