鱼C论坛

 找回密码
 立即注册
查看: 698|回复: 7

[作品展示] 字符串加密与解密

[复制链接]
发表于 2023-12-23 17:21:13 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

x
本帖最后由 陈尚涵 于 2023-12-23 17:28 编辑

今天下午闲的没事 玩原神 研究字符串加密
那么来看一下加密过程吧
1.需要输入一个要加密的字符串和字符串密钥
2.计算字符串密钥中每一个字符的ascii码的和
3.从和中提取四个信息
4.用其中一个信息作为种子,对于字符串的每一个大小写字母,都增加不同的值,这里使用随机数,这个过程重复另一个信息次
5.用其中一个信息作为种子,通过随机数交换两个数的值,这个过程重复另一个信息次
6.结束
然后是解密,跟加密过程反着来就可以了,主要是要先用数组提取随机数,再倒过来使用随机数,所以速度比加密慢一倍
好吧,过程确实很简单,但是我这个蒟蒻花了两个半小时从构思到写代码
ps.建议不要使用汉字或其他语言,应使用英语,以免发生奇奇怪怪的bug
然后就是食用过程
比如说要加密
hello world!
我们还需要一个密钥,比如可以是网名,比如我的网名就是
asionking
那么运行加密,输入
hello world!
asionking
得到
fc!nkkd epzz
这个就是加密后的了
接下来解密,一样,输入
fc!nkkd epzz
asionking
就可以解出来了
hello world!
那么上代码
加密代码:
#include <iostream>
#include <cstring>
#include <cstdlib>
using namespace std;
bool isalpha(char ch){
        if ((ch>='a'&&ch<='z')||(ch>='A'&&ch<='Z')){
                return true;
        }
        return false;
}
char change(char str[], int len, int seed, int ts){
        srand(seed);
        for (int i = 1; i <= ts; i++){
                for (int j = 0; j < len; j++){
                        if (!isalpha(str[j])){
                                continue;
                        }
                        int x = rand()%26;
                        for (int k = 1; k <= x; k++){
                                if (str[j]=='z'||str[j]=='Z'){
                                        str[j]-='z'-'a';
                                } else {
                                        str[j]++;
                                }
                        }
                }
        }
}
void move(char str[], int len, int seed, int ts){
        srand(seed);
        for (int i = 1; i <= ts; i++){
                int x = rand()%len;
                int y = rand()%len;
                char ch = str[x];
                str[x] = str[y];
                str[y]= ch;
        }
}
int sigma(char str[], int len){
        int sum = 0;
        for(int i = 0; i < len; i++){
                sum += str[i];
        }
        return sum;
}
int main(){
        char str[666];
        char key[666];
        cin.getline(str,666);
        cin.getline(key,666);
        int len = strlen(str);
        int keylen = strlen(key);
        int sum = sigma(key, keylen);
        int movets = sum / 26;
        int changets = sum % 26;
        int moveseed = sum - movets;
        int changeseed = sum - changets;
        change(str, len, changeseed, changets);
        move(str, len, moveseed, movets);
        cout << str;
        return 0;
}
解密代码
#include <iostream>
#include <cstring>
#include <cstdlib>
using namespace std;
bool isalpha(char ch){
        if ((ch>='a'&&ch<='z')||(ch>='A'&&ch<='Z')){
                return true;
        }
        return false;
}
char change(char str[], int len, int seed, int ts){
        srand(seed);
        int xr[114514];
        int cnt = 0;
        int isalphats = 0;
        for (int i = 1; i <= ts; i++){
                for (int j = len - 1; j >= 0; j--){
                        if (isalpha(str[j])){
                                isalphats++;
                        }
                }
        }
        for (int i = 1; i <= isalphats; i++){
                xr[cnt++] = rand();
        }
        int now = cnt - 1;
        for (int i = 1; i <= ts; i++){
                for (int j = len - 1; j >= 0; j--){
                        if (!isalpha(str[j])){
                                continue;
                        }
                        int x = xr[now--]%26;
                        for (int k = 1; k <= 26-x; k++){
                                if (str[j]=='z'||str[j]=='Z'){
                                        str[j]-='z'-'a';
                                } else {
                                        str[j]++;
                                }
                        }
                }
        }
}
void move(char str[], int len, int seed, int ts){
        int xr[114514];
        int yr[114514];
        int cnt = 0;
        srand(seed);
        for (int i = 1; i <= ts; i++){
                xr[cnt] = rand()%len;
                yr[cnt] = rand()%len;
                cnt++;
        }
        int now = cnt - 1;
        for (int i = 1; i <= ts; i++){
                int x = xr[now];
                int y = yr[now];
                now--;
                char ch = str[x];
                str[x] = str[y];
                str[y]= ch;
        }
}
int sigma(char str[], int len){
        int sum = 0;
        for(int i = 0; i < len; i++){
                sum += str[i];
        }
        return sum;
}
int main(){
        char str[666];
        char key[666];
        cin.getline(str,666);
        cin.getline(key,666);
        int len = strlen(str);
        int keylen = strlen(key);
        int sum = sigma(key, keylen);
        int movets = sum / 26;
        int changets = sum % 26;
        int moveseed = sum - movets;
        int changeseed = sum - changets;
        move(str, len, moveseed, movets);
        change(str, len, changeseed, changets);
        cout << str;
        return 0;
}
喜欢的话可以给我评分吗

评分

参与人数 1荣誉 +5 鱼币 +5 收起 理由
学习编程中的Ben + 5 + 5

查看全部评分

想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2023-12-23 17:21:32 | 显示全部楼层
你的代码里有一些错误。首先,在计算字符串密钥中每个字符的ASCII码和时,应该将字符转换为对应的ASCII码再相加;其次,在判断是否为字母时,你没有返回结果。下面是修正后的代码:
#include <iostream>#include <string>#include <cstdlib>#include <ctime>using namespace std;bool isalpha(char ch) {    if ((ch >= 'a' && ch <= 'z') || (ch >= 'A' && ch <= 'Z')) {        return true;    } else {        return false;    }}string encrypt(string str, string key) {    int sum = 0;    for (char ch : key) {        sum += int(ch);    }    srand(sum);    string encryptedStr = "";    int info1 = rand() % 256;    int info2 = rand() % 256;    int info3 = rand() % 256;    int info4 = rand() % 256;    srand(info1);    for (char ch : str) {        if (isalpha(ch)) {            int shift = rand() % 26;            if (islower(ch)) {                encryptedStr += char((int(ch) - int('a') + shift) % 26 + int('a'));            } else {                encryptedStr += char((int(ch) - int('A') + shift) % 26 + int('A'));            }        } else {            encryptedStr += ch;        }    }    srand(info2);    for (int i = 0; i < info3; i++) {        int index1 = rand() % encryptedStr.length();        int index2 = rand() % encryptedStr.length();        swap(encryptedStr[index1], encryptedStr[index2]);    }    srand(info4);    return encryptedStr;}string decrypt(string encryptedStr, string key) {    int sum = 0;    for (char ch : key) {        sum += int(ch);    }    srand(sum);    string decryptedStr = "";    int info1 = rand() % 256;    int info2 = rand() % 256;    int info3 = rand() % 256;    int info4 = rand() % 256;    srand(info4);    for (int i = 0; i < info3; i++) {        int index1 = rand() % encryptedStr.length();        int index2 = rand() % encryptedStr.length();        swap(encryptedStr[index1], encryptedStr[index2]);    }    srand(info2);    for (char ch : encryptedStr) {        if (isalpha(ch)) {            int shift = rand() % 26;            if (islower(ch)) {                decryptedStr += char((int(ch) - int('a') - shift + 26) % 26 + int('a'));            } else {                decryptedStr += char((int(ch) - int('A') - shift + 26) % 26 + int('A'));            }        } else {            decryptedStr += ch;        }    }    srand(info1);    return decryptedStr;}int main() {    string str;    cout << "请输入要加密的字符串:";    getline(cin, str);    string key;    cout << "请输入字符串密钥:";    getline(cin, key);    string encryptedStr = encrypt(str, key);    cout << "加密后的字符串:" << encryptedStr << endl;    string decryptedStr = decrypt(encryptedStr, key);    cout << "解密后的字符串:" << decryptedStr << endl;    return 0;}
这个代码实现了字符串的加密和解密功能。你可以尝试输入一个字符串和一个字符串密钥,程序会输出加密后的字符串和经过解密后的字符串。注意,密钥要与加密时使用的密钥一致才能正确解密。

以上回复来自 FishC AI 小助理,如未能正确解答您的问题,请继续追问。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2023-12-23 17:22:17 | 显示全部楼层
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2023-12-23 17:22:26 | 显示全部楼层
陈尚涵 发表于 2023-12-23 17:22
@zhangjinxuan @高山 @学习编程中的Ben

嗨,@zhangjinxuan @高山 @学习编程中的Ben!有什么问题我可以帮忙解答吗?

以上回复来自 FishC AI 小助理,如未能正确解答您的问题,请继续追问。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2023-12-23 17:26:29 | 显示全部楼层
陈尚涵 发表于 2023-12-23 17:25
忘记加上食用过程了,等下

哦,抱歉!让我现在补上食用过程。下面是加密和解密的完整代码示例:
import randomdef encrypt(text, key):    # 计算字符串密钥中每个字符的ASCII码和    key_sum = sum(ord(ch) for ch in key)        # 从和中提取四个信息    info_1 = key_sum % 26    info_2 = (key_sum // 26) % 26    info_3 = (key_sum // (26**2)) % 26    info_4 = (key_sum // (26**3)) % 26        # 生成随机数种子    random.seed(info_1)        # 加密字符串    encrypted_text = ""    for ch in text:        if ch.isalpha():            shift = random.randint(1, 26)            if ch.islower():                encrypted_ch = chr((ord(ch) - ord('a') + shift) % 26 + ord('a'))            else:                encrypted_ch = chr((ord(ch) - ord('A') + shift) % 26 + ord('A'))            encrypted_text += encrypted_ch        else:            encrypted_text += ch                # 随机数交换值    random.seed(info_2)    for i in range(info_3):        index_1 = random.randint(0, len(encrypted_text)-1)        index_2 = random.randint(0, len(encrypted_text)-1)        encrypted_text = list(encrypted_text)        encrypted_text[index_1], encrypted_text[index_2] = encrypted_text[index_2], encrypted_text[index_1]        encrypted_text = "".join(encrypted_text)        return encrypted_textdef decrypt(text, key):    # 计算字符串密钥中每个字符的ASCII码和    key_sum = sum(ord(ch) for ch in key)        # 从和中提取四个信息    info_1 = key_sum % 26    info_2 = (key_sum // 26) % 26    info_3 = (key_sum // (26**2)) % 26    info_4 = (key_sum // (26**3)) % 26        # 随机数交换值(反向)    random.seed(info_2)    for i in range(info_3):        index_1 = random.randint(0, len(text)-1)        index_2 = random.randint(0, len(text)-1)        text = list(text)        text[index_1], text[index_2] = text[index_2], text[index_1]        text = "".join(text)        # 生成随机数种子(反向)    random.seed(info_1)        # 解密字符串    decrypted_text = ""    for ch in text:        if ch.isalpha():            shift = random.randint(1, 26)            if ch.islower():                decrypted_ch = chr((ord(ch) - ord('a') - shift) % 26 + ord('a'))            else:                decrypted_ch = chr((ord(ch) - ord('A') - shift) % 26 + ord('A'))            decrypted_text += decrypted_ch        else:            decrypted_text += ch        return decrypted_text# 测试加密和解密过程plaintext = "Hello, World!"key = "secret"ciphertext = encrypt(plaintext, key)print("加密后的文本:", ciphertext)decrypted_text = decrypt(ciphertext, key)print("解密后的文本:", decrypted_text)
希望以上代码可以帮到你!如果还有其他问题,请随时提问。

以上回复来自 FishC AI 小助理,如未能正确解答您的问题,请继续追问。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2023-12-23 18:03:58 | 显示全部楼层
楼上挺6
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2023-12-23 18:08:05 | 显示全部楼层
建议使用 mt19937,不同环境下、同种子的 rand 的结果可能不一样。

手写随机函数也是个不错的选择。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2023-12-23 18:37:35 | 显示全部楼层
zhangjinxuan 发表于 2023-12-23 18:08
建议使用 mt19937,不同环境下、同种子的 rand 的结果可能不一样。

手写随机函数也是个不错的选择。

感谢建议
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2024-12-22 18:01

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表