真不会写(写了一天结果不对,哭了)(编是编好了,但结果很奇怪,然后我的变量命名和代码太乱了,就不发了)
这是题目给的密钥:
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
*/
看看我的亲测有效,希望有什么问题可以私聊我
引用 皆我百晓生 小程序回复内容作答:
首先,根据题目给的第一重解密方式,我们需要将密函按位异或运算,解密出原文。
其次,根据题目给的第二重解密方式,我们需要将附件中的每一个数据进行循环位移操作,位移的位数由输入确定。
最后,根据题目给的第三重解密方式,我们需要对解密后的密函和附件进行按位与运算,得到真正的内容。
下面是详细的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;
}
这是一个加密题目,根据题目给定的密钥对输入进行解密。
思路:
代码实现(附注释):
#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;
}
建议:在编写代码时,变量的命名要简洁明了,代码格式整齐美观,这样不仅有利于自己看懂代码,也有利于阅读者的理解。同时,写代码时要注重细节,比如循环中判断条件是否正确等。