首页 > 试题广场 >

字符串加密

[编程题]字符串加密
  • 热度指数:140428 时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C++ 32M,其他语言64M
  • 算法知识视频讲解
有一种技巧可以对数据进行加密,它使用一个单词作为它的密匙。下面是它的工作原理:首先,选择一个单词作为密匙,如TRAILBLAZERS。如果单词中包含有重复的字母,只保留第1个,将所得结果作为新字母表开头,并将新建立的字母表中未出现的字母按照正常字母表顺序加入新字母表。如下所示:

A B C D E F G H I J K L M N O P Q R S T U V W X Y Z

T R A I L B Z E S C D F G H J K M N O P Q U V W X Y (实际需建立小写字母的字母表,此字母表仅为方便演示)

上面其他用字母表中剩余的字母填充完整。在对信息进行加密时,信息中的每个字母被固定于顶上那行,并用下面那行的对应字母一一取代原文的字母(字母字符的大小写状态应该保留)。因此,使用这个密匙, Attack AT DAWN (黎明时攻击)就会被加密为Tpptad TP ITVH。

请实现下述接口,通过指定的密匙和明文得到密文。

数据范围: ,保证输入的字符串中仅包含小写字母


输入描述:

先输入key和要加密的字符串



输出描述:

返回加密后的字符串

示例1

输入

nihao
ni

输出

le
#include <stdio.h>
#include <string.h>

int main() {

//key: nihao
//raw : abcdefghijklmnopqrstuvwxyz
//cipher:nihaobcdefgjklmpqrstuvwxyz

char key[128];
char content[128];

scanf("%s", key);
scanf("%s", content);

char cipher[32] = {0}; //table
int flag[26] = {0};

int cipherLen = 0;
int len = strlen(key);
for(int i = 0;i < len;i++){
if(0 != flag[key[i] - 'a']){
continue;
}
cipher[cipherLen++] = key[i];
flag[key[i] - 'a'] = 1;
}

for(int i=0;i < 26;i++){
if(0 != flag[i]){
continue;
}
cipher[cipherLen++] = 'a' + i;
}

len = strlen(content);
for(int i=0; i < len;i++){
printf("%c",cipher[content[i] - 'a']);
}
printf("\n");

return 0;
}
发表于 2024-02-19 08:57:46 回复(0)
#include <stdio.h>
#include <string.h>
//判断字符c在不在字符串里面,如果在就返回0,不在就返回1
int campare(char str[],int n,char c)
{
    for(int i = 0;i<n;i++)
    {
        if(str[i] == c)
            return 0;
    }
    return 1;
}

int main() {
    char key[101] = {'\0'};
    char password[101] = {'\0'};
    while (scanf("%s %s", key,password) != EOF) {
        char ret[26] = {'\0'};
        int num = 0;
        for(int i = 0;i<strlen(key);i++)
        {
            //如果字符key[i]不在ret数组里面就把key[i]字符加在ret数组后面
            if(campare(ret,num,key[i]))
            {
                ret[num] = key[i];
                num++;
            }
        }
        char alpha[26] = {'a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z'};
        for(int i = 0;i<26;i++)
        {
            //把26个字母中每出现在ret数组里面字符一次加在数组ret后面
            if(campare(ret,num,alpha[i]))
            {
                ret[num] = alpha[i];
                num++;
            }
        }
        for(int i = 0;i<strlen(password);i++)
        {
            printf("%c",ret[password[i]-'a']);
        }
    }
    return 0;
}
发表于 2023-10-16 11:41:55 回复(0)
#include <string.h>
#include <stdio.h>
#include <stdlib.h>

void GetTrueKey(char trueKey[], char key[], int len, char otherKey[])
{
    int bit = -1;
    int hash[256] = {0};
    for(int i = 0; i < len; i++){
        if(hash[key[i]] == 0){
            hash[key[i]] = 1;
            trueKey[++bit] = key[i];
        }
    }
    trueKey[++bit] = 0;
    int cnt = -1;
    for(int i = 'a'; i <= 'z'; i++){
        if(hash[i] == 0){
            otherKey[++cnt] = i;
        }
    }
    otherKey[++cnt] = 0;
}

int main()
{
    char key[100] = {0};
    char s[101] = {0};
    scanf("%s", key);
    scanf("%s", s);
    char trueKey[27] = {0};
    char otherKey[27] = {0};
    GetTrueKey(trueKey, key, strlen(key), otherKey);
    strcat(trueKey, otherKey);
    for(int i = 0; i < strlen(s); i++){
        printf("%c", trueKey[s[i]-'a']);
    }
    return 0;
}

发表于 2023-10-06 09:17:38 回复(0)
#include <stdio.h>
#include <string.h>

int main() {
    char encode[26] = {};
    char key[100] = {};
    char key2[100] = {};
    char str[100] = {};
    scanf("%s", key);
    scanf("%s", str);

    int len = strlen(key);

    //去重key得到新的key2
    int count[26] = {0};
    int p = 0;
    for (int i = 0; i < len; i++) {
        if (count[key[i] - 'a'] == 0) {
            key2[p] = key[i];
            p++;
            count[key[i] - 'a'] = 1;
        }
    }

    //用key2建立密码表
    for (int i = 0; i < p; i++) {
        encode[i] = key2[i];
    }
    for (int i = 0; i < 26; i++) {
        if (count[i] == 0) {
            encode[p] =  i + 'a';
            count[i] = 1;
            p++;
        }
    }

    //输出加密字符串
    int len2 = strlen(str);
    for (int i = 0; i < len2; i++) {
        printf("%c", encode[str[i] - 'a']);
    }
    return 0;
}

发表于 2023-02-26 14:54:35 回复(0)
题目说明了只有小写输入
#include <stdio.h>
#include <string.h>

int main(){
    char key[100];char txt[100];
    scanf("%s",key);scanf("%s",txt);
    char translate[26]={0};
    for(int i=0;i<strlen(key);i++){//按密钥生成转换表并去重
        int j=0;int flag=0;
        while(translate[j]){
            if(translate[j]==key[i]){
                flag=1;
                break;
            }
            j++;
        }
        if(!flag){
            translate[j++]=key[i];
        }
    }
    int l=strlen(translate);
    for(int i=0;i<26;i++){//补全26位的转换表
        int flag=0;
        for(int j=0;j<l;j++){
            if(translate[j]=='a'+i){
                flag=1;
                break;
            }
        }
        if(!flag){
            translate[l++]='a'+i;
        }
    }
    for(int i=0;i<strlen(txt);i++){
        txt[i]=translate[txt[i]-'a'];
        printf("%c",txt[i]);
    }
}


发表于 2022-06-06 11:01:22 回复(0)
#include <stdio.h>
#define    N    100
int main()
{
    char key[N],str[N],seek[26];
    int i=0,j,len=0,arr[26]={0};
    gets(key);
    gets(str);
    while(key[i]!='\0')
    {
        if(len==0)
        {
            seek[len++]=key[i];
            arr[key[i]-'a']=1;
        }
        else
        {
            for(j=0;j<len;j++)
            {
                if(seek[j]==key[i])
                    break;
            }
            if(j==len)
            {
                seek[len++]=key[i];
                arr[key[i]-'a']=1;
            } 
        }
        i++;
    }
    for(i=len;i<26;i++)
    {
        for(j=0;j<26;j++)
        {
            if(arr[j]==0)
            {
                seek[i]='a'+j;
                arr[j]=1;
                break;
            }
        }
    }
    i=0;
    while(str[i]!='\0')
    {
        printf("%c",seek[str[i]-'a']);
        i++;
    }
    return 0;
}

发表于 2022-04-27 11:36:39 回复(0)
/*
注意:仅包含小写字母
思路:建立顺序字母表dict作为字典
     用一个数组标记26个字母,遍历密匙,遇到字母标记为selected并加入字典,重复字母跳过
     遍历完密匙,不存在的字母就放到后面
     最后获取明文,根据dict置换字母
时空复杂度:O(m+n);  O(1)
*/
#include <stdio.h>
#include <string.h>

int main(void)
{
    char in[101];
    char key[101];
    
    while( scanf("%[^\n]", key) != EOF){
        getchar();
        scanf("%[^\n]", in);
        getchar();
        char dict[26] = {0};
        int selected[26] = {0};
        
        int j = 0;
        for(int i=0; i < strlen(key); i++){       //遍历密匙
            if( !selected[ key[i]-'a' ] ){        //如果是未被选中过的字母
                selected[ key[i]-'a' ] = 1;    
                dict[j] = key[i];                 //选中并添加到字典dict
                j++;
            }
        }
        for(int i=0; i<26; i++){                  //密匙中没有的字母,按字母表顺序放到dict后面
            if( !selected[i] ){
                dict[j] = 'a' + i;
                j++;
            }
        }

        for(int i=0; i<strlen(in); i++){
            if( ' ' != in[i] ){
                in[i] = dict[ in[i]-'a' ];        //根据dict替换小写字母
            }
        }
        printf("%s\n", in);
    }

    return 0;
}

发表于 2022-01-22 17:19:35 回复(0)
第一次写的时候睿智了 忘记加break跳出循环操作。
#include<stdio.h>
#include<stdlib.h>
#include<string.h>

int main()
{
    char str[101]={0};
    while(gets(str))
    {
        char alpha[26]={0};  /*lower alphabet*/
        char encrypt[26]={0}; /*lower alphabet*/
        int count[200]={0}; /*lower alphabet*/
        char source[101]={0};
        gets(source);
        int len = strlen(str);
        int sourlen=strlen(source);
        int i,j,k;
        for(i=0;i<26;i++)
        {
            alpha[i]='a'+i;
        }
        j=0;
        for(i=0;i<len;i++)
        {
            if(count[str[i]]==0)
            {
                encrypt[j]=str[i];
                count[str[i]]++;
                j++;
            }
        }
        while(j<26)
        {
            for(i=0;i<26;i++)
            {
                if(count[alpha[i]]==0)
                {
                    encrypt[j]=alpha[i];
                    j++;
                }
            }
        }
        for(i=0;i<sourlen;i++)
        {
            for(k=0;k<26;k++)
            {
                if(alpha[k]==source[i])
                {
                    source[i]=encrypt[k];
                    break;
                }
            }
        }
        printf("%s\n",source);
    }
    return 0;
}


发表于 2021-12-14 01:04:59 回复(0)
按照题目要求:
1.先对密钥进行处理
2.将下方的数组补全
3.根据需要加密的字符串找出下放数组对应的字符输出即可
代码中做了一个转化成大写的封装

#include<stdio.h>
#include<string.h>

char shang[26] = {'A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z'};
char xia[27] = {0};

// 转化大写
char toUper(char in) {
    if (in >= 'a' && in <= 'z') {
        in-=32;
    }
    return in;
}
// 查找需要加密的字符
char findChar(char in) {
    for (int i = 0; i < strlen(shang); i++) {
        if( shang[i] == in || shang[i] == (in - 32)) {
            if (in >= 'a' && in <= 'z') {
                return xia[i] + 32; // 返回小写
            } else {
                return xia[i]; // 返回大写
            }
        }
    }
    return 0;
}

int main(){
    char key[100] = {0};
    char in[100] = {0};
    while (gets(key) && gets(in)) {
        // 处理密钥,转化为大写,去掉重复字母,存放到xia数组中
        for (int i = 0; i < strlen(key); i++) {
            key[i] = toUper(key[i]);
            int j = 0;
            for (j = 0; j < strlen(xia); j++) {
                if(xia[j] == key[i]) {
                    break;
                }
            }
            if(j == strlen(xia)) {
                xia[j] = key[i];
            }
        }
        // 补全下方的xia数组
        for (char p = 'A'; p <= 'Z'; p++){
            int j = 0;
            for (j = 0; j < strlen(xia); j++) {
                if (xia[j] == p) {
                    break;
                }
            }
            if (j == strlen(xia)) {
                xia[j] = p;
            }
        }
        for (int i = 0; i < strlen(in); i++){
            printf("%c", findChar(in[i]));
        }
        printf("\n");
        memset(xia, 0, sizeof(xia)); // 重置全局数组,否则第二组数据报错
    }
}
发表于 2021-08-14 00:24:12 回复(0)
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef struct list
{
    int val;
    struct list *next;
}List;
int main()
{
    char key[100];
    int i,j;
    while(gets(key))
    {
        int len=strlen(key);
        char base[26];
        int count=0;
        int flag=1;
        for(i=0;i<len;i++)
        {
            if(key[i]<='Z'&&key[i]>='A')
            {
                key[i]=key[i]-'A'+'a';
            }
            flag=1;
            for(j=0;j<count;j++)
            {
                if(base[j]==key[i])
                {
                    flag=0;
                    break;
                }
            }
            if(flag==1)
            {
                base[count++]=key[i];
            }
        }
        for(i=0;i<26;i++)
        {
            flag=1;
            for(j=0;j<count;j++)
            {
                if(base[j]==(i+'a'))
                {
                    flag=0;
                    break;
                }
            }
            if(flag==1)
            {
                base[count++]=(i+'a');
            }
        }
        char input[100];
        gets(input);
        len=strlen(input);
        for(i=0;i<len;i++)
        {
            if(input[i]<='Z'&&input[i]>='A')
            {
                input[i]=input[i]-'A'+'a';
                input[i]=base[input[i]-'a']-'a'+'A';
            }
            else
            {
                input[i]=base[input[i]-'a'];
            }
        }
        printf("%s\n",input);
    }
    return 0;
}

发表于 2021-07-15 20:07:36 回复(0)