C语言相关的练习断手之作

真不会写(写了一天结果不对,哭了)(编是编好了,但结果很奇怪,然后我的变量命名和代码太乱了,就不发了)

img

img

这是题目给的密钥:

unsigned char password[70]={71,114,101,97,116,32,105,100,101,97,108,32,98,117,116,32,116,104,114,111,117,103,104,32,115,101,108,102,108,101,115,115,32,115,116,114,117,103,103,108,101,32,97,110,100,32,115,97,99,114,105,102,105,99,101,32,116,111,32,97,99,104,105,101,118,101,46};`

这是例子:

//输入
9 23 19 132 6 192 6 27 10 15 13 94 29 14 3 69 4 17 29 18 73 18 24 78
201 172 222 239 206 5 254 237 221 207 172 20 252 61 206 188 21 175 253 254 68 190 126 215
3

//输出
78 101 118 101 114 32 103 111 110 110 97 32 103 105 118 101 32 121 111 117 32 117 112 46

#include<stdio.h>
#include<stdlib.h>
int getNumberCount(int number){
    int index =0;
    while(number >0){
        number = number >> 1;
        index++;
    }

    return 1 << (index - 1);
}

unsigned char numberLeftMove( unsigned char number, int numberCount, int loopMoveCount)
{
    unsigned char retNumber = number;
    for(int i = 0; i < loopMoveCount; i++){
        if((retNumber & numberCount) > 0){
            retNumber = ((retNumber^numberCount)  << 1) + 1;
        }else{

            retNumber = retNumber << 1;
        }

    }
    return retNumber;
}

unsigned char numberRightMove( unsigned char number, int numberCount, int loopMoveCount)
{
    unsigned char retNumber = number;
    for(int i = 0; i < loopMoveCount; i++){
        if((retNumber & 1) > 0){
            retNumber = (retNumber >> 1) | numberCount;
        }else{

            retNumber = retNumber >> 1 ;
        }
    }
    return retNumber;
}
int main() {
    unsigned char password[71] = {71,114,101,97,116,32,105,100,101,97,108,32,98,117,116,32,116,104,114,111,117,103,104,32,115,101,108,102,108,101,115,115,32,115,116,114,117,103,103,108,101,32,97,110,100,32,115,97,99,114,105,102,105,99,101,32,116,111,32,97,99,104,105,101,118,101,46};
    unsigned char SecretLetters[71] = {0}; //密函
    unsigned char annex[71] = {0}; //附件
    int loopMoveCount = 0;  //循环位移数
    int secreCount = 0; //密函长度
    int annexCount = 0; //附件长度
    char endChar;
    int  i;
    int  numberCount = 0;
    while(1){
        scanf("%hhu%c", &SecretLetters[secreCount++], &endChar);
        if(endChar == '\n'){
            break;
        }
    }
    while(1){
        scanf("%hhu%c", &annex[annexCount++], &endChar);
        if(endChar == '\n'){
            break;
        }
    }
    scanf("%d", &loopMoveCount);
    for (i = 0; i < secreCount; i++) {
        SecretLetters[i] ^= password[i];
    }
    for (i = 0; i < annexCount; i++) {
        numberCount = getNumberCount(annex[i]);
        if(loopMoveCount>0){
            annex[i] = numberLeftMove(annex[i], numberCount, loopMoveCount);
        }
        else {
            annex[i] = numberRightMove(annex[i], numberCount,-loopMoveCount);
        }
    }
     for (i = 0; i < secreCount; i++) {
        SecretLetters[i] = SecretLetters[i] & annex[i];
        if(i > 0){
            printf(" ");
        }
        printf("%hhu", SecretLetters[i]);
    }
    return 0;
}
/*
9 23 19 132 6 192 6 27 10 15 13 94 29 14 3 69 4 17 29 18 73 18 24 78
201 172 222 239 206 5 254 237 221 207 172 20 252 61 206 188 21 175 253 254 68 190 126 215
3
*/

img

看看我的亲测有效,希望有什么问题可以私聊我

引用 皆我百晓生 小程序回复内容作答:
首先,根据题目给的第一重解密方式,我们需要将密函按位异或运算,解密出原文。

其次,根据题目给的第二重解密方式,我们需要将附件中的每一个数据进行循环位移操作,位移的位数由输入确定。

最后,根据题目给的第三重解密方式,我们需要对解密后的密函和附件进行按位与运算,得到真正的内容。

下面是详细的C语言代码实现:

#include<stdio.h>

// 按位异或解密密函
void xorDecryption(unsigned char* data, int len, unsigned char* password) {
    for (int i = 0; i < len; i++) {
        data[i] ^= password[i%70];
    }
}

// 循环左移解密附件
void leftShiftDecryption(unsigned char* data, int len, int shift) {
    for (int i = 0; i < len; i++) {
        data[i] = ((data[i] << shift) | (data[i] >> (8 - shift))) & 0xFF;
    }
}

// 按位与解密密函和附件
void andDecryption(unsigned char* data, int len) {
    for (int i = 0; i < len; i++) {
        data[i] &= data[i+len];
    }
}

int main() {
    unsigned char password[70] = {71,114,101,97,116,32,105,100,101,97,108,32,98,117,116,32,116,104,114,111,117,103,104,32,115,101,108,102,108,101,115,115,32,115,116,114,117,103,103,108,101,32,97,110,100,32,115,97,99,114,105,102,105,99,101,32,116,111,32,97,99,104,105,101,118,101,46};

    int len;
    scanf("%d", &len);
    unsigned char text[len];
    for (int i = 0; i < len; i++) {
        scanf("%hhu", &text[i]);
    }

    unsigned char attachment[len];
    for (int i = 0; i < len; i++) {
        scanf("%hhu", &attachment[i]);
    }

    int shift;
    scanf("%d", &shift);


    xorDecryption(text, len, password);
    leftShiftDecryption(attachment, len, shift);
    andDecryption(text, len);

    for (int i = 0; i < len; i++) {
        printf("%c", text[i]);
    }

    return 0;
}

注意,在本题中,我们需要将解密后的结果以ASCII字符的形式输出,所以在输出时需要使用%c格式化输出。



#include <stdio.h>

typedef unsigned char uchar;

void fun1(uchar *pwd, uchar *mh, int mhLen)
{
    for (int i = 0; i < mhLen; i++)
    {
        mh[i] ^= pwd[i];
    }
}

uchar moveFun(uchar fj, uchar move)
{
    uchar t;
    while (move--)
    {
        t = 0x80 & fj;
        fj <<= 1;
        t >>= 7;
        fj |= t;
    }
    return fj;
}

void fun2(uchar *fj, int mhLen, int move)
{
    for (int i = 0; i < mhLen; i++)
    {
        fj[i] = moveFun(fj[i], move);
    }
}

void fun3(uchar *mh, uchar *fj, int mhLen)
{
    for (int i = 0; i < mhLen; i++)
    {
        mh[i] &= fj[i];
    }
}

void print(uchar *mh, int mhLen)
{
    for (int i = 0; i < mhLen; i++)
    {
        printf("%d ", mh[i]);
    }
    printf("\n");
}

int main(void)
{
    uchar password[] = {71, 114, 101, 97, 116, 32, 105, 100, 101, 97, 108, 32, 98, 117, 116, 32, 116, 104, 114, 111, 117, 103, 104, 32, 115, 101, 108, 102, 108, 101, 115, 115, 32, 115, 116, 114, 117, 103, 103, 108, 101, 32, 97, 110, 100, 32, 115, 97, 99, 114, 105, 102, 105, 99, 101, 32, 116, 111, 32, 97, 99, 104, 105, 101, 118, 101, 46};

    uchar mh[70] = {9, 23, 19, 132, 6, 192, 6, 27, 10, 15, 13, 94, 29, 14, 3, 69, 4, 17, 29, 18, 73, 18, 24, 78};

    uchar fj[70] = {201, 172, 222, 239, 206, 5, 254, 237, 221, 207, 172, 20, 252, 61, 206, 188, 21, 175, 253, 254, 68, 190, 126, 215};
    int move = 3, mhLen = 24;

    fun1(password, mh, mhLen);

    fun2(fj, mhLen, move);
   
    fun3(mh, fj, mhLen);

    print(mh, mhLen);

    return 0;
}

试试

#include <stdio.h>

unsigned char password[70] = {71, 114, 101, 97, 116, 32, 105, 100, 101, 97, 108, 32, 98, 117, 116, 32, 116, 104, 114, 111, 117, 103, 104, 32, 115, 101, 108, 102, 108, 101, 115, 115, 32, 115, 116, 114, 117, 103, 103, 108, 101, 32, 97, 110, 100, 32, 115, 97, 99, 114, 105, 102, 105, 99, 101, 32, 116, 111, 32, 97, 99, 104, 105, 101, 118, 101};

void xor_decrypt(unsigned char *cipher_text, int len) {
    for (int i = 0; i < len; i++) {
        cipher_text[i] ^= password[i];
    }
}

void left_rotate(unsigned char *attachment_text, int len, int shift_value) {
    for (int i = 0; i < len; i++) {
        attachment_text[i] = (attachment_text[i] << shift_value) | (attachment_text[i] >> (8 - shift_value));
    }
}

void bitwise_and(unsigned char *cipher_text, unsigned char *attachment_text, int len) {
    for (int i = 0; i < len; i++) {
        cipher_text[i] &= attachment_text[i];
    }
}

int main() {
    unsigned char cipher_text[100];
    unsigned char attachment_text[100];
    int shift_value;

    // 读取输入
    int cipher_len = 0;
    int attachment_len = 0;
    while (scanf("%hhu", &cipher_text[cipher_len]) == 1) {
        cipher_len++;
    }
    while (scanf("%hhu", &attachment_text[attachment_len]) == 1) {
        attachment_len++;
    }
    scanf("%d", &shift_value);

    // 解密第一重(按位异或)
    xor_decrypt(cipher_text, cipher_len);

    // 解密第二重(循环左移)
    left_rotate(attachment_text, attachment_len, shift_value);

    // 解密第三重(按位与)
    bitwise_and(cipher_text, attachment_text, cipher_len);

    // 输出解密结果
    for (int i = 0; i < cipher_len; i++) {
        printf("%hhu ", cipher_text[i]);
    }

    return 0;
}


这是一个加密题目,根据题目给定的密钥对输入进行解密。

思路:

  • 将输入读入,将密钥对应的 ASCII 码转换成字符。
  • 对于每一个输入,进行解密操作。
  • 解密操作流程:将输入与密钥异或,得到一个新的字符,输出即可。

代码实现(附注释):

#include <stdio.h>

int main() {
    unsigned char password[70] = {
        // 给定的密钥
        71,114,101,97,116,32,105,100,101,97,108,32,98,117,116,32,116,104,114,111,117,103,104,32,
        115,101,108,102,108,101,115,115,32,115,116,114,117,103,103,108,101,32,97,110,100,32,115,
        97,99,114,105,102,105,99,101,32,116,111,32,97,99,104,105,101,118,101,46
    };

    int input[1000];    // 存放输入
    int cnt = 0;        // 输入数字个数
    int key_len = 70;   // 密钥长度

    // 读取输入
    while (scanf("%d", &input[cnt]) != EOF) {
        cnt++;          // 读入数字个数加1
    }

    // 对每个输入进行解密操作
    for (int i = 0; i < cnt; i++) {
        int key = password[i % key_len];    // 取密钥中的字符
        int res = input[i] ^ key;           // 异或操作,得到新的字符
        printf("%c", res);                  // 输出字符
    }

    return 0;
}

建议:在编写代码时,变量的命名要简洁明了,代码格式整齐美观,这样不仅有利于自己看懂代码,也有利于阅读者的理解。同时,写代码时要注重细节,比如循环中判断条件是否正确等。