LA 3213 古老的密码

https://icpcarchive.ecs.baylor.edu/index.php?option=com_onlinejudge&Itemid=8&category=15&page=show_problem&problem=1214

题意:

给定两个字符串,通过交换位置和一一映射判断能否使得两个字符串相同。

 

思路:

这题训练指南说得不准确,没有说到交换位置这一条件。既然可以交换位置,那我们只需要统计每个字符串中每个字母出现的次数,只要两个字符串中字母数相同并且出现次数也相同那就一定能转换成功。

 1 #include<iostream> 
 2 #include<algorithm>
 3 #include<string>
 4 #include<cstring>
 5 using namespace std;
 6 
 7 char s1[105], s2[105];
 8 int p1[26], p2[26];
 9 
10 int main()
11 {
12     ios::sync_with_stdio(false);
13     //freopen("D:\\txt.txt", "r", stdin);
14     while (cin >> s1)
15     {
16         cin >> s2;
17         int len1 = strlen(s1);
18         int len2 = strlen(s2);
19         memset(p1, 0, sizeof(p1));
20         memset(p2, 0, sizeof(p2));
21         for (int i = 0; i < len1; i++)
22             p1[s1[i] - 'A']++;
23         for (int i = 0; i < len2; i++)
24             p2[s2[i] - 'A']++;
25         sort(p1, p1 + 26);
26         sort(p2, p2 + 26);
27         int flag = 1;
28         for (int i = 0; i < 26;i++)
29         if (p1[i] != p2[i])
30         {
31             flag = 0;
32             break;
33         }
34         if (flag)  cout << "YES" << endl;
35         else cout << "NO" << endl;
36     }
37 }

 

转载于:https://www.cnblogs.com/zyb993963526/p/6523497.html

门限密码是指将一个秘密分成多个部分,只有当这些部分汇聚在一起时,才能重构出原来的秘密。在密码学中,门限密码被广泛应用于多方安全计算,数据解密和认证等领域。下面我们将简要介绍如何使用Python来实现门限密码。 首先,我们需要安装必要的库。可以使用pip命令安装pycryptodome,它提供了实现门限密码所需的密钥生成和数据加密等函数。 ``` pip3 install pycryptodome ``` 之后,我们要设置门限,假设我们需要将秘密分成5份,每份至少需要3份才能还原出秘密。我们可以使用Shamir的门限密码方案来生成密钥,Shamir方案的实现可以使用pycryptodome库中的函数。 ```python from Crypto.Util.number import getRandomInteger, GCD, inverse from Crypto.Util import number # 参数k表示有k个份秘密,n表示至少需要n份秘密才能还原原始秘密 def generate_shamir_key(k, n): p = number.getPrime(512) a = getRandomInteger(512) b = getRandomInteger(512) % p # 检查p,b是否互质,如果不是,重新生成随机数 while GCD(a, p) != 1 or GCD(b, p) != 1: p = number.getPrime(512) a = getRandomInteger(512) b = getRandomInteger(512) % p shares = [] for i in range(1, k + 1): x = i y = (a * x + b) % p shares.append((x, y)) return shares ``` 在生成密钥的过程中,我们首先生成一个512位的素数p,随机选择两个512位的整数a和b。然后检查a和p,b和p是否互质,确保生成的密钥是安全的。最后我们用x在1到k之间的数值求出对应的y值,并将x和y保存在一个元组中加入密钥列表中。 当我们需要还原秘密时,可以使用Lagrange插值法计算密钥: ```python from collections import Iterable # 参数shares是一个元组列表,表示秘密分成了多少份,以及每份的x和y值 # 参数x是需要还原秘密的x值 def lagrange_interpolation(shares, x): def product(nums): # 计算序列中所有元素的乘积 p = 1 for num in nums: p *= num return p # 检查shares是否为一个可迭代的序列 if isinstance(shares, Iterable): sss = 0 for j, share_j in enumerate(shares): x_j, y_j = share_j p = [(x - x_j) / (j - x_j) for j, share_j in enumerate(shares) if x_j != j] # p 的极限为 -x / j,分母为0时,不做计算 sss += (y_j * product(p)) sss % p[0] return sss ``` Lagrange插值法的实现较为简单,我们首先检查输入的shares参数是否为可迭代序列,然后依次根据每个元组计算Lagrange插值多项式的乘积,最后得出密钥。 使用门限密码对数据进行加密时,我们首先将原始数据切分成n份,并将每份数据分别使用不同的密钥进行加密。当需要解密时,至少需要收集到n份密文才能还原出原始数据。 ```python from Crypto.Cipher import PKCS1_OAEP from Crypto.PublicKey import RSA def encrypt_data(data, keys): encrypted_data = [] for i in range(len(keys)): key = keys[i] message = data[i].to_bytes(16, byteorder="big") rsa_key = RSA.construct(key) cipher = PKCS1_OAEP.new(rsa_key) encrypted_data.append(cipher.encrypt(message)) return encrypted_data def decrypt_data(data, keys): decrypted_data = [] for i in range(len(keys)): key = keys[i] rsa_key = RSA.construct(key) cipher = PKCS1_OAEP.new(rsa_key) decrypted_data.append(int.from_bytes(cipher.decrypt(data[i]), byteorder="big")) return decrypted_data ``` 在进行加密时,我们首先将原始数据分成n份,并对每份数据使用一个不同的密钥进行加密。在进行解密时,我们需要指定解密的密钥,将收到的密文使用相应的密钥进行解密,并将解密后的数据保存在一个列表中。 综上所述,我们可以使用Python编写一个完整的门限密码程序。该程序首先生成密钥,然后将原始数据进行切分并使用不同的密钥进行加密。当需要解密数据时,至少收集到n份密文即可还原出原始数据。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值