Hill encryption Algorithm (sixth session of Hunan Normal University computer Program design Competition) hnuoj11552

Source: Internet
Author: User
Tags gcd

Decrypt

Time limit : 1000ms, Special time limit:2500ms, Memory Limit: 65536KB

Total Submit Users: 2, Accepted users: 0

problem 11552: No Special Judgement

Problem description

   cryptography, there is a method of encryption, called Hill encryption method. The encryption steps are as follows:  
Step1: String to be encrypted s={s[0], s[1], ...} (for simplicity, in the case, the string s contains only lowercase letters) press s[n-1, a->0 >2, ..., y->24, z->25 rules converted to an array of shapes a={a[0], a[1], ..., a[n-1]};
Step2: Divides the array A into k parts of equal length, each part length is L (guaranteed to k*l=s the length of the string s to be encrypted)
SETP3: Add each part to the left by one L * L matrix A, the result vector all the values to 26 modulo replace the original part, to obtain a new array  
B={b[0], b[1], ..., b[n-1]},  
is the element in B that satisfies:  
(B[i * k],b[i * k + 1], ..., b[i * k + (L-1)]) = (A[i * k],a[i * k + 1], ..., a[i * k + (L-1)]) *a
Step4: Press the number in array B to 0->a, 1->b, 2->c, ..., 24->y, 25->z, convert the rules to ciphertext   For example: Encryption July, Matrix A=[11 8;3 7] (semicolon denotes another line)
Step1: Convert July to an array a={9, one, one, and one};
STEP2: Divide a into {9, 20},{11, 24} two parts  
Step3: Because [9,] * [one 8;3 7] = [159, 212]
[11, 24] * [11 8;3 7]=[19 3, []]
b=[159%, 212%, 193%, [3, 4, one,]
Step4: Ciphertext is DELW
Your task is: give you ciphertext and matrix A, the original string &NB SP;

Input

The first behavior is an integer T (0 < T < 20), which represents the number of groups of data.
The first behavior of each set of data is an encrypted string consisting of a lowercase letter with a length of not more than 10000.
The second behavior is an integer m (0 < M <= 100 and the length of the string can be divisible by m), indicating that matrix A is a matrix of m*m
followed by M-line, M-integer per line, representing matrix A, input data guaranteed matrix A main diagonal element and 26-factor

Output

For each set of data, the output line is the original text corresponding to the ciphertext

Sample Input

2

Delw

2

11 8

3 7

Pabqlzqii

3

1 14 2

5 9 2

4 7 3

Sample Output

July

qvtusjkcm

Problem Source

Hunnu Contest

Hill decryption; Need to find the inverse matrix first;

I can only go through the first group .... Great gods, please explain ...

#include <math.h> #include <string.h> #include <malloc.h> #include <iostream> #include < Iomanip> #include <stdio.h>using namespace std; #define N 105//define the maximum order of the Phalanx as the declaration part of the 10//function double Matdet (                    Double *p, int n);    To find the determinant of a matrix double creat_m (double *p, int M, int n, int k);                    Computes the algebraic my-type void print (double *p, int n) of the matrix element A (m, n);    Output matrix N*nbool Gauss (double a[][n], double b[][n], int N);                The inverse matrix of a square matrix bdouble a[n][n],b[n][n];int C[n][n];d ouble determ is obtained by using the Gaussian elimination method of partial principal element;    Define the determinant of the matrix//int zimu[26];int gcd (int a,int b) {if (!b) return A; GCD (b,a%b);}    void Print (int mm[],int k) {/* for (int i=0; i<k; i++) {printf ("%d", mm[i]); } printf ("\ n"); */for (int i=0; i<k; i++) {for (int j=0; j<k; J + +) {printf ("%d", C I        [j]);    } printf ("\ n");   }//Double tp[105]= {0};    int tp[105]={0}; for (int i=0; i<k; i++)//column {for (int j=0; j<k; J + +)//Line | |        MM line {tp[i]+=mm[j]*c[j][i];//printf ("tp=%d\tmm=%d\tb=%d\n", Tp[i],mm[j],c[j][i]);        }} for (int i=0; i<k; i++) {//int tmp= (int) (tp[i]);//printf ("%d\t", TMP);  printf ("%c", ((Tp[i])%26+26)%26+ ' a ');  while (tp[i]<0) tp[i]+=26;    printf ("%c\n", (int) (tp[i])%26+ ' a '); }//printf ("\ n");}    int main () {//Freopen ("Xier.txt", "R", stdin);            Double *buffer, *p;                Define array first address pointer variable int row, num;    Defines the number of rows and matrix elements of a matrix//int i, J;    int n;//for (int i=0;i<26;i++)//zimu[i]=i;    int t,len,m,mo[105];    Char mi[10005];    scanf ("%d", &t);        while (t--) {scanf ("%s", MI);        Len=strlen (MI);        scanf ("%d", &n);        Row=n;        num = 2*row*row;        Buffer = (double *) calloc (num, sizeof (double));        Allocate memory unit p = buffer;                for (int i=0, i<n; i++) {for (int j=0; j<n; J + +) {scanf ("%lf", &a[i][j]);            *P++=A[I][J];    }} determ = Matdet (buffer, row);        Find the determinant of the whole matrix//printf ("determ=%lf\n", determ);        int D=GCD ((int) (determ), 27); d= (int) determ*27/d;        printf ("***************************************d=%d\n", D);                for (int i = 0; i < row; i++)//Inverse matrix {for (int j = 0; J < Row; J + +) {            * (p+j*row+i) = creat_m (buffer, I, J, Row) *d/determ;        }} print (P, row);        Free (buffer);                Free memory space for (int i=0; i<len; i++) {//printf ("mi=%c\n", Mi[i]);                mo[i%n]=mi[i]-' a ';                printf ("i=%d\tmo=%d\n", i%n,mo[i%n]);            if ((i+1)%n==0) Print (mo,n); } printf ("\ n"); for (int i=0, i<n; i++)//{//for (int j=0; j<n; j + +)//{//Print    F ("%lf", A[i][j]);  //        }    //      printf ("\ n");                }//if (Gauss (a,b,n))//{/* for (int i = 0; i < n; i++) {                cout << SETW (4);                for (int j = 0; J < N; j + +) {cout << b[i][j] << setw (10);            } cout << Endl; }*///}} return 0;} -----------------------------------------------//function: Matrix (n*n) determinant//Entry parameter: The first address of the matrix, the number of rows//Return values: The determinant value of the matrix//----------    ------------------------------------double Matdet (double *p, int n) {int r, C, M;    int lop = 0;    Double result = 0;    Double mid = 1;            if (n! = 1) {lop = (n = = 2)? 1:n;            Control sum cycle, if 2 order, then loop 1 times, otherwise n for (m = 0; m < lop; m++) {mid = 1; Order sum, the sum of the main diagonal elements multiplied by for (R = 0, C = m; r < N; r++, C + +) {mid = Mid * (* (p+r*n+c%n)            );        } result + = Mid; } for (m = 0; M < Lop;            m++) {mid = 1; Subtract in reverse order, minus the second diagonal element product for (r = 0, c = n-1-m+n; r < N; r++, c--) {mid = Mid * (* (p+r*            n+c%n));        } result-= mid;    }} else result = *p; return result;} ----------------------------------------------------------------------------//function: To find the algebraic my of element a (M, n) in K*k matrix//Inlet parameter : The first address of the k*k matrix, the subscript m,n of the matrix element A, the number of rows k//The return value: Algebraic my of element a (M, N) in the k*k matrix//------------------------------------------------------    ----------------------Double creat_m (double *p, int M, int n, int k) {int len;    int I, J;    Double Mid_result = 0;    int sign = 1;    Double *p_creat, *p_mid;            Len = (k-1) * (k-1); The algebraic my of the K-order matrix is the k-1-order Matrix P_creat = (double*) calloc (len, sizeof (double));    Allocate memory Unit p_mid = p_creat; for (i = 0, i < K; i++) {for (j = 0; J < K; J + +) {if (i! = m && J! = N)//will be in addition to section I               All elements outside the row and column J are stored to the memory unit with the P_mid-first address { *p_mid++ = * (P+I*K+J); }}} sign = (m+n)%2 = = 0?    1:-1;    Algebraic my front positive, minus sign Mid_result = (double) Sign*matdet (P_creat, k-1);    Free (p_creat); return mid_result;} -----------------------------------------------------//function: Print n*n matrix//Ingress parameters: N*n Matrix's first address, number of rows in the matrix n//return value: No return value//--------    ---------------------------------------------void print (double *p, int n) {int i, J;        for (i = 0; i < n; i++) {//cout << SETW (4);            for (j = 0; J < N; j + +) {c[i][j]= (int) *p++;   while (c[i][j]<0) c[i][j]+=26;        cout << setiosflags (ios::right) << *p++ << SETW (10);    }//cout << Endl; }}//------------------------------------------------------------------//function: Using the Gaussian elimination method of partial principal element to find the inverse matrix of square a b//inlet parameter: input phalanx, Output Phalanx, matrix order//return value: TRUE or false//-------------------------------------------------------------------bool Gauss (    Double A[][n], double b[][n], int N) {int I, j, K;    Double Max, temp;Double T[n][n]; Temporary matrix//The A matrix is stored in the temporary matrix T[n][n] for (i = 0; i < n; i++) {for (j = 0; J < N; j + +) {T I        [j] = a[i][j]; }}//Initialize B matrix for unit array for (i = 0; i < n; i++) {for (j = 0; J < N; j + +) {B[i][j] = (i = = j)?        (double) 1:0;        }} for (i = 0; i < n; i++) {//find main element max = T[i][i];        K = i; for (j = i+1; J < N; j + +) {if (Fabs (T[j][i]) > Fabs (max)) {max = t[j][                I];            K = J;                }}//If the main element row is not the first row, do the line exchange if (k! = i) {for (j = 0; J < N; j + +) {                temp = T[i][j];                T[I][J] = T[k][j];                T[K][J] = temp;                B accompanying Exchange temp = B[i][j];                B[I][J] = B[k][j];            B[K][J] = temp; }}//To determine if the principal is 0, if the matrix A is not a full rank matrix, there is no inverse matrix if (t[I][i] = = 0) {cout << "there is no inverse matrix!";        return false;        }//Elimination of column I of a to remove rows other than line element temp = T[i][i];        for (j = 0; J < N; j + +) {T[i][j] = t[i][j]/temp;        The elements on the main diagonal become 1 b[i][j] = b[i][j]/temp; Adjoint calculation} for (j = 0; J < N; j + +)//No. 0 row, nth row {if (j! = i)//not                Line I {temp = t[j][i]; for (k = 0; k < n; k++)//J row Element-I row element *j column I row element {t[j][k] = t[j][k]-T[i][k]*te                    mp                B[J][K] = b[j][k]-b[i][k]*temp; }}}} for (int i=0, i<n; i++) {for (int j=0; j<n; J + +) {B[i][j        ]*=determ;    }//printf ("\ n"); } return true;


Hill encryption Algorithm (sixth session of Hunan Normal University computer Program design Competition) hnuoj11552

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.