BugkuCTF栅栏密码解题记录(原理+C语言实现)

一、简述

近期在BugkuCTF上碰到了一个栅栏密码的题目,刚开始用了在线的解密工具解密出了flag。但是仅用在线工具直接得到结果肯定是不行的,于是通过AI了解了栅栏密码的原理以及加密和解密思路,并用C语言实现了一下。

二、思路与概括

根据查看的资料,它本质上是一种置换密码 (只改变字符位置,不改变内容),所以按个人理解是只是将内容中的字符或数字打乱了顺序,因此可以尝试通过循环去输出所有的可能性组合,但这会计算爆炸,所以不可行。

按照栅栏密码的加密思路,是将一整段密码分为了多份,再从这个多份里面去挨个抽取值,可以理解为:

将N张牌,按照数量分为两份或多份,然后开始在第一份中抽取一个,再在第二份中抽取一个,循环抽取,每次收取的牌的数量为当前循环的下标值。

破解原理就是:首先要知道密文总长度是多少,这样才能进行分段计算,然后需要根据已知的层数,去对整段密文进行分段,使其符合当初抽牌的时候一样。

用 总长度 / 层数 = 加密时共计抽取了多少次

然后循环 i 控制行数,j 控制列数,i 的值决定了本次要抽牌的次数,而 j 的值决定了本次需要抽那一张牌,然后输出这个排列就是解密后的答案。

三、实现结果

四**、C**源码

cpp 复制代码
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

void decrypt_railfence(char* ciphertext, int key) {
	int i,j;
    int len = strlen(ciphertext); //22
//    printf("函数中密文的长度:%d\n",len);
    char plaintext[len + 1];  // 23
//    printf("函数中plaintext的值是:%s\n",plaintext);
    int segment = len / key; // 每组的长度 11
//    printf("函数中组的长度:%d\n",segment);
    
    for (i = 0; i < segment; i++) {
        for (j = 0; j < key; j++) {
            plaintext[i * key + j] = ciphertext[i + j * segment];
        }
    }
    plaintext[len] = '\0';
    printf("Key是: %d 结果是: %s\n", key, plaintext);
}

main(){
	char text_pwd[100];
	int lan_num = 0;
	printf("请输入栅栏的密文:"); 
	scanf("%s",&text_pwd);
//	printf("这里是输入的栅栏的密文:%s\n\n",text_pwd);
	printf("请输入栅栏的层数:");
	scanf("%d",&lan_num);
//	printf("这里是输入栅栏的层数:%d\n\n",lan_num);
	decrypt_railfence(text_pwd,lan_num);
	return 0;
}
相关推荐
咸鱼2.01 小时前
【java入门到放弃】跨域
java·开发语言
skiy2 小时前
java与mysql连接 使用mysql-connector-java连接msql
java·开发语言·mysql
一念春风2 小时前
智能文字识别工具(AI)
开发语言·c#·wpf
桦02 小时前
【C++复习】:继承
开发语言·c++
何仙鸟2 小时前
GarmageSet下载和处理
java·开发语言
wefly20173 小时前
免安装!m3u8live.cn在线 M3U8 播放器,小白也能快速上手
java·开发语言·python·json·php·m3u8·m3u8在线转换
薛先生_0993 小时前
js学习语法第一天
开发语言·javascript·学习
报错小能手4 小时前
深入理解 Linux 虚拟内存管理
开发语言·操作系统
和沐阳学逆向4 小时前
我现在怎么用 CC Switch 管中转站,顺手拿 Codex 举个例子
开发语言·javascript·ecmascript
小仙女的小稀罕4 小时前
听不清重要会议录音急疯?这款常见AI工具听脑AI精准转译
开发语言·人工智能·python