zoukankan      html  css  js  c++  java
  • 乘数密码 扩展欧几里得求逆元

    题目来源:http://acm.nyist.net/JudgeOnline/problem.php?pid=769

    乘数密码

    时间限制:1000 ms  |  内存限制:65535 KB
    难度:1
     
    描述

    乘数密码也是一种替换密码,其加密变换是将明文字母串逐位乘以密钥k并进行模运算,数学表达式如下:

    E(m)=k*m mod q,   gcd(k,q)=1 (即k,q互素)。

    当k与q互素时,明文字母加密成密文字母的关系为一一映射。

    现有一经过乘法加密的密文,请破译出它的明文。

     
    输入
    输入包含多组数据,不超过1000组。
    每组包含一个字符串和一个正整数k,字符串全部由大写字母组成,长度不超过50,k是与q互素的数,q=26,k<26。
    输出
    每组输出数据单独占一行,输出对应的明文。
    样例输入
    ILOVEYOU 3
    
    样例输出
    UVWHKIWY

    分析:
    1:加密 E(m) = k*m % q 且 gcd(k,q)=1;
    2:解密 m = E(m) * k^-1(mod q) mod q 。
    k^-1(mod q)为 kx≡1(mod q)中 x 的值。 
    代码如下:
    #include<iostream>
    #include<stdlib.h>
    #include<stdio.h>
    #include<math.h>
    #include<string.h>
    #include<string>
    #include<queue>
    #include<algorithm>
    #include<map>
    #define N 55
    using namespace std;
    char str[N];
    // 扩展欧几里得 , 得到 x, y, d等式 ax + by =d
    int extend_gcd(int a, int b, int&x, int &y)
    {
        if(b==0) {x=1; y=0; return a;}
        int d=extend_gcd(b,a%b, y,x);
        y-=a/b *x;
    }
    // **************求逆元 ,在 已知 gcd(k,n) =1 的情况
    // kx =1(mod n)
    int mod_reverse(int k, int n)
    {
        int x,y;
        extend_gcd(k,n,x,y)%n;
         return (x%n +n)%n;
    }
    int main(){
        while(cin>>str)
        {
            int k;
            scanf("%d",&k);
            for(int i=0; i<strlen(str) ; i++)
            {
                str[i]  = (str[i] -'A') * mod_reverse(k,26) %26 +'A';
                printf("%c",str[i]);
            }
            printf("
    ");
        }
        return 0;
    }
     
     
  • 相关阅读:
    struct
    python Hbase Thrift pycharm 及引入包
    python 性能鸡汤
    hbase 0.96 单机伪分布式配置文件及遇到的问题 find命令
    ubuntu下配置protobuf
    hadoop 2.2.0 eclipse 插件编译 及相关eclipse配置图解
    hadoop2.2.0 单机伪分布式(含64位hadoop编译) 及 eclipse hadoop开发环境搭建
    install ubuntu
    ubuntu wubi安装注意事项
    HBase eclipse开发环境搭建
  • 原文地址:https://www.cnblogs.com/zn505119020/p/3606374.html
Copyright © 2011-2022 走看看