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;
    }
     
     
  • 相关阅读:
    inspector 只读属性
    使用MongoDB
    【Roslyn C#】Runtime环境Unity读取字符串代码
    Unity使用LoadImage 读取byte[]图片时,会出现白边问题
    团队中避免不可维护代码的措施
    Unity点到线段的最短距离
    判断点是否在多边形内部
    Unity 根据前后帧位置自动旋转
    停止Unity在运行时脚本修改重新编译的情况
    KI子线段树 / AKEE SegmentTree
  • 原文地址:https://www.cnblogs.com/zn505119020/p/3606374.html
Copyright © 2011-2022 走看看