您的位置:首页 > 编程语言 > PHP开发

php实现弗吉尼亚算法加密解密以及重合指数分析

2015-03-21 07:22 721 查看
哈工大密码学原理实验一:古典密码体制的实践与分析

实验项目描述:

Z26上的维吉尼亚密码体制:

(1)编写密钥为 (k1,k2,…,kn)的维吉尼亚加、解密程序,其中n值由用户输入,密钥随机产生;

(2)用 (1)实现的加、减密程序对一段英文(其长度应较长
) 进加、解密;
(3)针对(2),统计明文和密文中各字符出现的频率。要求给出
n=4,16 两种情况下的频率统计结果;
(4)针对(2),计算明文和密文的重合指数。要求给出
n=1,2,4,8,16,32,64, 128,256 几种情况下的计算结果。

<!-- virginia.php -->
<?php

/***************  凯撒密码表 ***************

ABCDEFGHIJKLMNOPQRSTUVWXYZ
BCDEFGHIJKLMNOPQRSTUVWXYZA
CDEFGHIJKLMNOPQRSTUVWXYZAB
DEFGHIJKLMNOPQRSTUVWXYZABC
EFGHIJKLMNOPQRSTUVWXYZABCD
FGHIJKLMNOPQRSTUVWXYZABCDE
GHIJKLMNOPQRSTUVWXYZABCDEF
HIJKLMNOPQRSTUVWXYZABCDEFG
IJKLMNOPQRSTUVWXYZABCDEFGH
JKLMNOPQRSTUVWXYZABCDEFGHI
KLMNOPQRSTUVWXYZABCDEFGHIJ
LMNOPQRSTUVWXYZABCDEFGHIJK
MNOPQRSTUVWXYZABCDEFGHIJKL
NOPQRSTUVWXYZABCDEFGHIJKLM
OPQRSTUVWXYZABCDEFGHIJKLMN
PQRSTUVWXYZABCDEFGHIJKLMNO
QRSTUVWXYZABCDEFGHIJKLMNOP
RSTUVWXYZABCDEFGHIJKLMNOPQ
STUVWXYZABCDEFGHIJKLMNOPQR
TUVWXYZABCDEFGHIJKLMNOPQRS
UVWXYZABCDEFGHIJKLMNOPQRST
VWXYZABCDEFGHIJKLMNOPQRSTU
WXYZABCDEFGHIJKLMNOPQRSTUV
XYZABCDEFGHIJKLMNOPQRSTUVW
YZABCDEFGHIJKLMNOPQRSTUVWX
ZABCDEFGHIJKLMNOPQRSTUVWXY

******************************************/

// 生成输入长度的密钥
function makecode($num) {
$re = '';
$s = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ';
while(strlen($re)<$num) {
$re .= $s[rand(0, strlen($s)-1)]; 			// 从$s中随机产生一个字符
}
return $re;
}

// 弗吉尼亚算法加密
function v_encode($mstr, $mkey) {
$nstr = strtoupper($mstr);          			// 将明文转成大写
$nstr = str_replace(chr(32),'',$nstr);          // 去空格
$key = str_split($mkey);                        // 将密钥由字符串转成数组
$str = str_split($nstr);
$keylen = count($key);                          // 计算密钥长度
$strlen = count($str);
$arr = array();
for( $i = 0; $i < $strlen; $i++) {
$arr[$i] = chr(((ord($str[$i])-65) + (ord($key[$i%$keylen])-65))%26+65);
}
echo '原文加密:'."<br />";
echo '原文:'."<br />".$mstr."<br />";
echo '密钥:'."<br />".$mkey."<br />";
echo '明文:'."<br />".$nstr."<br />";
return $arr;
}

// 弗吉尼亚算法解密
function v_decode($ciphertext, $mkey){
$key = str_split($mkey);
$keylen = count($key);
$strlen = count($ciphertext);
$arr = array();
for( $i = 0; $i < $strlen; $i++) {
if(ord($ciphertext[$i]) >= ord($mkey[$i%$keylen])){
$arr[$i] = chr(ord($ciphertext[$i]) - ord($mkey[$i%$keylen]) + 65);
}
else {
$arr[$i] = chr(ord($ciphertext[$i]) + 26 - ord($mkey[$i%$keylen]) + 65);
}
}
echo '<br />'.'<br />'.'密文解密:'.'<br />';
echo '密文:'."<br />".implode("",$ciphertext).'<br />';
echo '密钥:'."<br />".$mkey."<br />";
echo '明文:'."<br />".implode("",$arr)."<br />"."<br />";
}

// 计算明文,密文重合指数
function computeOneIC($mstr,$flag){
$strlen = count($mstr);
$mstr = implode("", $mstr);
$arr = array();
$numerator = 0;
for( $i = 0; $i <= 25; $i++){
$arr[$i] = substr_count($mstr, chr($i+65));            // 统计每个字母在数组中出现个数
$numerator += $arr[$i] * ($arr[$i] - 1);
}
$denominator = $strlen * ($strlen - 1);
$IC = $numerator / $denominator;
if($flag){
echo '明文重合指数:'.$IC.'<br />';
}
else{
echo '密文重合指数:'.$IC.'<br />';
}
}

// 通过计算重合指数算出密钥长度
function computeIC($ciphertext){
$strlen = count($ciphertext);
$k = 0;
$IC = 0;
$sum = 0;
$arr = array();
echo "<br />"."密钥长度    重合指数<br />";
for( $length = 1; $length <= 256; $length++){                   // 密钥范围:1~256
for( $i = 0; $i <= 25; $i++){
$arr[$i] = 0;
}
for( $i = 0; $i < $strlen / $length; $i++){
$narr[$i] = 0;
}
for( $head = 0; $head < $strlen; $head += $length){			// 根据密钥长度处理数组
$arr[ord($ciphertext[$head])-65] += 1;
}
$numerator = 0;
for( $i = 0; $i <= 25 ; $i++){
$numerator += $arr[$i] * ($arr[$i] - 1);                   // 分子
}
$denominator = ($strlen / $length) * (($strlen / $length)-1);    // 分母
$IC = $numerator / $denominator;
echo $length.'--------->'.$IC.'<br />';
if( $IC >= 0.064 && $IC <= 0.071){
echo "密钥长度:".$length.'<br />';
for( $i = 1; $i <= $length; $i++){
for( $j = 0; $j < $strlen; $j + $i){
$narr[ord($ciphertext[$j])-65] += 1;
}
$max = $narr[$k];
for( $k = 0; $k <= 25; $k++){
if( $narr[$k] > $max ){
$max = $narr[$k];
}
}
$onekey = cha(ord($max) - 69);
echo $onekey;                      // 按位得出密钥
}
exit();
}
}
}

// 主程序
if(isset($_POST["sub"])){
$mkey = $_POST["data"];
$mkey = intval($mkey);
$mkey = makecode($mkey);
$mstr = 'your input'; 		 //原文
$ciphertext = v_encode($mstr, $mkey);  			// 加密
echo '密文:'."<br />".implode("",$ciphertext);
}

v_decode($ciphertext, $mkey);						// 解密
computeOneIC(str_split($mstr), 0);					// 原文重合指数
computeOneIC($ciphertext, 1);						// 密文重合指数
computeIC($ciphertext);								// 计算重合指数得出密钥长度

?>


<!-- input.php -->
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Input.php</title>
</head>
<body>
<form action="virginia.php" method="post" >
<p>请输入密钥长度:</p>
<input name="data" type="text" />
<input type="submit" name="sub" value="提交"/>
</form>
</body>
</html>
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: