Hill密码

希尔密码(Hill Password)是运用基本矩阵论原理的替换密码,由Lester S. Hill在1929年发明。每个字母当作26进制数字:A=0, B=1, C=2... 一串字母当成n维向量,跟一个n×n的矩阵相乘,再将得出的结果MOD26。注意用作加密的矩阵(即密匙)在\mathbb_^n必须是可逆的,否则就不可能译码。只有矩阵的行列式和26互质,才是可逆的

#include<stdio.h>  
#include<string.h>
#include<ctype.h>
#include<stdlib.h>

int A[1000][1000];//转化矩阵
int a[1000][1000];//单位矩阵[A E]
int B[1000][1000];//矩阵的逆矩阵A^(-1)
int ming[1000][1000];//明文矩阵
int mi[1000][1000];//密文矩阵
int n;//矩阵的阶数
void input()//输入数据
{
    int i, j;
    for( i = 1; i <= n; i++ )
        for( j = 1; j <= n; j++ )
            A[i][j] = rand() % 26;
    memcpy( a, A, sizeof( A ) );//将矩阵A复制给a
    for( i = 1; i <= n; i++ )//将矩阵变成[a E]的形式,E为单位矩阵
    {
        for( j = n + 1; j <= 2*n; j++ )
        {
            if( i + n == j )
                a[i][j] = 1;
            else
                a[i][j] = 0;
        }
    }
}

void output()     //输出函数
{
    int i,j;
    printf("矩阵A的元素\n");
    for( i = 1; i <= n; i++ )
    {
        for( j = 1; j <= n; j++ ){
            printf("%d ",A[i][j]);
        }
        printf("\n");
    }
    printf("A矩阵的逆矩阵B为\n");
    for( i = 1; i <= n; i++ )//输出A矩阵的逆矩阵B
    {
        for( j = 1; j <= n; j++ )
        {
            B[i][j] = a[i][j+n];
            printf("%d ",B[i][j]);

        }
        printf("\n");
    }
}

int Extend_Gcd( int a, int b, int &x, int &y )//扩展欧几里得算法
{
    if( b == 0 )
    {
        x = 1;
        y = 0;
        return a;
    }
    int r = Extend_Gcd( b, a % b, x, y );
    int t = x;
    x = y;
    y = t - a / b * y;
    return r;
}

int ni( int a)//求逆a*x=1(mod n)
{
    int x, y;
    int d = Extend_Gcd( a, 26, x, y );
    if( d == 1 )
        return ( x % 26 + 26 ) % 26;
    else
        return -1;
}

int gaosi()//高斯-约当消元求A矩阵的逆矩阵B
{
    int i, j, k;
    for( k = 1; k <= n; k++ )//高斯-约当消元
    {
        int Ni = ni( a[k][k] );
        if( Ni == -1 ) return 0;
        for( i = k + 1; i <= 2 * n; i++ )
            a[k][i] = ( a[k][i] *  Ni % 26 + 26 ) % 26;
        for( i = 1; i <= n; i++ )
        {
            if( i == k ) continue;
            for( j = k + 1; j <= 2 * n; j++ )
                a[i][j] = ( ( a[i][j] - a[i][k] * a[k][j] % 26 ) % 26 + 26 ) % 26;
        }
    }
    return 1;
}

void jiami()    //加密过程
{
    int i, j, k;
    char mingstr[100];
    char mingc;

    printf("请输入明文");
    scanf("%s",&mingstr);
    int len = strlen( mingstr );
    if( len % n )
    {
        for( i = len; i < len/n*n+n; i++)
            mingstr[i] = ‘a‘;
        mingstr[i] = ‘\0‘;
    }
    puts( mingstr );
    int Len = strlen( mingstr );
    for( i = 1; i <= Len/n; i++ )//将明文分成len/n段
    {
        for( j = 1; j <= n; j++ )//求每一段的明文转换为矩阵
        {
            if( mingstr[(i-1)*n+j-1] >= ‘a‘ && mingstr[(i-1)*n+j-1] <= ‘z‘ )
                ming[i][j] = mingstr[(i-1)*n+j-1] - ‘a‘;
            else
                ming[i][j] = mingstr[(i-1)*n+j-1] - ‘A‘;
        }
    }
    for( k = 1; k <= Len/n; k++ )//求len/n段的密文矩阵
    {
        for( i = 1; i <= n; i++ )//利用矩阵的乘法
        {
            mi[k][i] = 0;
            for( j = 1; j <= n; j++ )
                mi[k][i] = ( mi[k][i] + ming[k][j] * A[j][i] % 26 + 26 ) % 26;
        }
    }
    printf("密文为");
    for( i = 1; i <= Len/n; i++ )//输出密文
    {
        for( j = 1; j <= n; j++ )
        {
            mingc = mi[i][j] + ‘A‘;

            printf("%c",mingc);
        }

    }
    printf("\n");
}

void jiemi()   //解密过程
{
    int i, j, k;
    char mistr[100];
    char mingc;
    printf("请输入密文");
    scanf("%s",&mistr);
    int len = strlen( mistr );
    for( i = 1; i <= len/n; i++ )//将密文分成len/n段
    {
        for( j = 1; j <= n; j++ )//求每一段的密文转换为矩阵
        {
            if( mistr[(i-1)*n+j-1] >= ‘a‘ && mistr[(i-1)*n+j-1] <= ‘z‘ )
                mi[i][j] = mistr[(i-1)*n+j-1] - ‘a‘;
            else
                mi[i][j] = mistr[(i-1)*n+j-1] - ‘A‘;
        }
    }
    for( k = 1; k <= len/n; k++ )//求len/n段的明文矩阵
    {
        for( i = 1; i <= n; i++ )//利用矩阵的乘法
        {
            ming[k][i] = 0;
            for( j = 1; j <= n; j++ )
                ming[k][i] = ( ming[k][i] + mi[k][j] * B[j][i] % 26 + 26 ) % 26;
        }
    }
    printf("明文为");
    for( i = 1; i <= len/n; i++ )//输出明文
    {
        for( j = 1; j <= n; j++ )
        {
            mingc = ming[i][j] + ‘A‘;

            printf("%c",mingc);
        }

    }
    printf("\n");

}

int main()
{
int flag;
    do{
        printf( "1.加密2.解密3.退出\n");
        scanf("%d",&flag);
        if(flag==1)
        {printf("请输入加密矩阵的阶数n:");
        scanf("%d",&n);
        do{
            input();//数据输入
        }while( !gaosi() );
         output();
         jiami();}//加密过程
        else if(flag==2)
        {jiemi();//解密过程
        }
        else if(flag!=1&&flag!=2&&flag!=3) printf("输入错误,请重新输入!\n");
    }while(flag!=3);
      return 0;
}
时间: 2024-12-25 07:39:51

Hill密码的相关文章

信息安全-2:python之hill密码算法[原创]

转发注明出处:http://www.cnblogs.com/0zcl/p/6106513.html 前言: hill密码算法我打算简要介绍就好,加密矩阵我用教材上的3*3矩阵,只做了加密,解密没有做,不过我觉得会加密就会解密的~~       一.hill算法原理 hill密码是一种多字母替代密码,由数学学Leste Hill于1929年研制成功.该密码算法取m个连续的明文字母,并用m个密文字母代替,用向量或矩阵表示为(这里取m=3,C和P是长度为3的列向量,K是3*3矩阵): 即:C=KP  

javascript实现playfair和hill密码算法

时至期末,补习信息安全概论作业.恰巧遇古典密码学算法中的playfair算法和hill算法,用javascript语言实现起来是在有趣,边查百度边编码,顺便好好补习一下javascript基础. playfair Playfair密码(英文:Playfair cipher 或 Playfair square)是一种替换密码.依据一个5*5的正方形组成的密码表来编写,表中排列有25个字母.对于英语中的26个字母,去掉最常用的Z,构成密码表. 实现思路: 1,编制密码表 密钥是一个单词或词组,密码表

4 多表代替密码之Hill 密码_1 矩阵工具类

在说明Hill加密之前要先复习线性代数的知识,主要是关于矩阵的一些运算和概念. 一.矩阵的逆: 定义方阵M的逆矩阵应该满足M*M^-1==I,其中I是单位矩阵,比如: 但是这个地方是对英文字母进行加密,所以矩阵中的数字都是模26的值,比如:   *  = 这个地方结果就应该mod26, 最后结果就是: 那么上面两个相乘的矩阵就互为逆矩阵. 这个地方要多说一下密码学中的mod运算,数学中-5%26结果肯定是-5,但是这个地方我们取值只能在0-25之间,所以-5%26的结果应该是21. 求解一个方阵

4 多表代替密码之Hill 密码 2实现

该解密方法的KEY 不是一个数或者一段字符串,而是一个矩阵, 比如有个3*3的KEY: 那么如果我们要加密一个长度为N的字符串, 那么把N除以3,分成M个3个字母组成的小段, 对每个小段尽心加密: 1. 将明文分成M个小段:{{p1,p2,p3},{p4,p5,p6}...{..pN}} 2. 对每个小段尽心加密: c1 = (k11*p1 + k21*p2 + k31*p3) c2= (k12*p1 + k22*p2 + k32*p3) c3= (k13*p1 + k23*p2 + k33*p

古典密码(Hill加密算法)

"Hill的加密与解密" Hill加密是另一种多字母代替密码,与多表代替密码不同的是,Hill密码要求将明文分成同等规模的若干个分组(最后一个分组涉及到填充),每一个分组被整体的加密代换,即希尔密码属于分组加密.Hill密码的算法思想是:将一个分组中的d个连续的明文字母通过线性变换转换为d个密文字母.这种变换由d个线性方程决定,其中每个字母被分配一个数值(0,1,...,25).解密只需要做一次逆变换就可以了,密钥就是变换矩阵本身. 设明文为一维矩阵m,密文为一维矩阵c,密钥用k矩阵表

信息安全-1:python之playfair密码算法详解[原创]

转发注明出处: http://www.cnblogs.com/0zcl/p/6105825.html 一.基本概念 古典密码是基于字符替换的密码.加密技术有:Caesar(恺撒)密码.Vigenere(维吉尼尔)密码.Playfair密码.Hill密码-- 明文:未经过加密的信息:密文:加密后的信息 加密解密的过程:如下图 二.Caesar密码 这里我先简单讲下恺撒密码,咸觉挺简单的,后面再主要讲Playfair算法原理与编程. 基本原理: 在开拓罗马帝国的时候,恺撒担心信使会阅读他送给士兵的命

密码学基础知识(三)古典密码

说完了前面那些,想起个事,本系列依据内容主要来自<现代密码学>马春光编著.我就是学这本书的. 好了,古典密码就是古时候的密码,哈哈,逗你玩的,shannon的保密系统的通信理论发表前的都是古典密码,会在密码学简史中介绍这位牛人的. 学习古典密码学的意义:学习设计原理和分析方法 古典密码也是,俩门派:置换和代换,顾名思义,一个是换了个原来有的,一个是换了个原来没有的.学术点讲就是前者明文和密文空间一样,后者 不一样.你要是问我啥是明文空间和密文空间啊,我就呵呵.是M 和 C.m明文的集合,c密文

古典密码-多表密码体制

如果明文中不同的位置的同一明文字母在密文中对应的密文字母不同,则称为多表密码体制. 代表性的多表密码: 1.Vigenere密码 2.Beaufort密码 3.running-key密码 4.Vernam密码 5.Hill密码 例子: 1.Vigenere密码加密: 设明文   m=m1m2...mn 密钥      k = k1k2...kn 则密文   c=Ek(m)=c1c2...cn 其中      ci=(mi+ki)(mod 26),(i=1,2,...,n) Vigenere密码解

第三章 传统加密技术

1 对称加密模型 对称加密防范的五个基本成分: 明文:原始的消息或是数据,是算法的输入 加密算法:加密算法对明文进行各种代替和变化 密钥:加密算法的输入,密钥独立于明文和算法,算法根据所用的特定密钥产生不同的输出 密文:算法的输入 解密算法:是加密算法的逆运算.输入密文和密钥,输出原始明文. 传统密码的安全使用满足如下两个要求: 机密算法必须足够强:即使对方拥有一定数量的密文和产生这些秘文的明文,他也不能破译密文或是发现密钥 发送者和接受者必须在某种安全模式下获得密钥并且必须保护密钥的安全. 对