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;
    }
     
     
  • 相关阅读:
    vim删除以#,空格开头的行
    Element-ui 中对表单进行验证
    VUE页面实现加载外部HTML方法
    vue-cli2嵌入html
    文字环绕图片
    LocalDate计算两个日期相差天数
    springboot+vue脚手架使用nginx前后端分离
    通过 Netty、ZooKeeper 手撸一个 RPC 服务
    Spring Native 项目,把 Spring 项目编译成原生程序!
    印象笔记吐槽
  • 原文地址:https://www.cnblogs.com/zn505119020/p/3606374.html
Copyright © 2011-2022 走看看