You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

土耳其字符导致凯撒加解密失效的原因问询(VS C++/CodePage1254)

凯撒加密解密对土耳其字符失效的问题解决

问题描述

使用Visual Studio C++项目编写的凯撒加密解密代码,处理非土耳其字符时运行正常,但采用Turkish(Windows)-CodePage 1254编码时,输入如“öğrenci”,解密后实际输出“§renci”,无法还原为原字符串。原代码如下:

#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
#include <stdio.h>
#include<stdlib.h>
#include<locale.h>
#include<conio.h>
#include<string.h>


void ceaserEncrypt(char* point) {
    setlocale(LC_ALL, "turkish");
    char msg0[100];
    char msg1[100];
    char* ptrmsg = msg1;
    printf("Şifrelenecek metni giriniz:");
    gets(msg0, sizeof(msg0));
    system("cls");
    int i;
    for (i = 0;msg0[i] != '\0';i++) {
        if (msg0[i] != ' ') {
            msg1[i] = msg0[i] + 5;
        }
        else {
            msg1[i] = ' ';
        }
    }
    msg1[i] = '\0';
    printf("encryption:%s", msg1);
    strcpy(point, msg1);
}
char a[100];
char* ptr = a;
void ceaserDecrypt(char str[]) {
    setlocale(LC_ALL, "turkish");
    char msg0[100];
    strcpy(msg0, str);
    int i;
    for (i = 0;i < strlen(msg0);i++) {
        if (msg0[i] != ' ') {
            msg0[i] = msg0[i] - 5;
        }
        else {
            msg0[i] = ' ';
        }
    }
    printf("\nDecryption:%s", msg0);


}

int main(){
ceaserEncrypt(ptr);
ceaserDecrypt(a);
return 0;
}

问题原因

原代码直接对字符的字节值进行加减操作,未考虑土耳其字符集(CodePage 1254)的特性:

  • 土耳其字母包含ç、ğ、ı、ö、ş、ü等特有字符,这些字符的字节值加减5后会跳出有效字母范围,变成非字母符号
  • 凯撒密码的核心是在对应语言的字母表内循环偏移,而非直接修改字节值,原逻辑未实现循环机制,导致字符偏移后无法正确还原

修正方案

定义土耳其字母表的大小写集合,加密解密时在字母表范围内循环偏移5位,确保字符始终保持在有效字母范围内:

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include<stdlib.h>
#include<locale.h>
#include<string.h>

// 土耳其字母表(含大小写,按CodePage 1254顺序)
const char turkish_lower[] = "abcçdefgğhıijklmnoöprsştuüvyz";
const char turkish_upper[] = "ABCÇDEFGĞHIİJKLMNOÖPRSŞTUÜVYZ";
const int turkish_len = sizeof(turkish_lower) - 1; // 去掉末尾的'\0'

// 找到字符在字母表中的索引,未找到返回-1
int find_char_index(char c, const char* alphabet) {
    for (int i = 0; alphabet[i] != '\0'; i++) {
        if (alphabet[i] == c) {
            return i;
        }
    }
    return -1;
}

void ceaserEncrypt(char* point) {
    setlocale(LC_ALL, "turkish");
    char msg0[100];
    char msg1[100];
    printf("Şifrelenecek metni giriniz:");
    fgets(msg0, sizeof(msg0), stdin);
    // 去掉fgets读取的换行符
    msg0[strcspn(msg0, "\n")] = '\0';
    system("cls");

    int i;
    for (i = 0; msg0[i] != '\0'; i++) {
        if (msg0[i] == ' ') {
            msg1[i] = ' ';
            continue;
        }
        int idx = find_char_index(msg0[i], turkish_lower);
        if (idx != -1) {
            // 小写字母循环偏移5位
            msg1[i] = turkish_lower[(idx + 5) % turkish_len];
            continue;
        }
        idx = find_char_index(msg0[i], turkish_upper);
        if (idx != -1) {
            // 大写字母循环偏移5位
            msg1[i] = turkish_upper[(idx + 5) % turkish_len];
            continue;
        }
        // 非土耳其字母保持原样
        msg1[i] = msg0[i];
    }
    msg1[i] = '\0';
    printf("encryption:%s\n", msg1);
    strcpy(point, msg1);
}

char a[100];
char* ptr = a;

void ceaserDecrypt(char str[]) {
    setlocale(LC_ALL, "turkish");
    char msg0[100];
    strcpy(msg0, str);

    int i;
    for (i = 0; msg0[i] != '\0'; i++) {
        if (msg0[i] == ' ') {
            msg0[i] = ' ';
            continue;
        }
        int idx = find_char_index(msg0[i], turkish_lower);
        if (idx != -1) {
            // 小写字母循环偏移-5位,避免负数取模问题
            msg0[i] = turkish_lower[(idx - 5 + turkish_len) % turkish_len];
            continue;
        }
        idx = find_char_index(msg0[i], turkish_upper);
        if (idx != -1) {
            // 大写字母循环偏移-5位
            msg0[i] = turkish_upper[(idx - 5 + turkish_len) % turkish_len];
            continue;
        }
        // 非土耳其字母保持原样
        msg0[i] = msg0[i];
    }
    printf("Decryption:%s\n", msg0);
}

int main(){
    ceaserEncrypt(ptr);
    ceaserDecrypt(a);
    return 0;
}

关键修改点

  • 替换不安全的gets为fgets,避免缓冲区溢出
  • 定义土耳其专属字母表,实现字符在字母表内的循环偏移
  • 增加大小写字母的判断逻辑,确保特殊字符正确偏移
  • 解密时通过+ turkish_len避免负数取模导致的异常

内容的提问来源于stack exchange,提问作者Orhun Tokdemir

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.14 17:26:05