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;
}
相关推荐
Dovis(誓平步青云)1 小时前
《QT学习第四篇:常见事件与UDP、TCP、文件系统、(锁、信号量、条件变量》
c语言·开发语言·汇编·qt
isyangli_blog10 小时前
OpenDayLight (Carbon 版本) 启动与组件安装
开发语言·php
vb20081110 小时前
FastAPI APIRouter
开发语言·python
Benszen10 小时前
KVM虚拟化解决方案
开发语言·perl
会编程的土豆10 小时前
Go 语言反射(Reflection)详解
开发语言·后端·golang
東雪木10 小时前
多线程与并发编程 专属复习笔记
java·开发语言·笔记·java面试
杨充10 小时前
1.3 浮点型数据设计灵魂
开发语言·python·算法
噜噜噜阿鲁~10 小时前
python学习笔记 | 11.3、面向对象高级编程-多重继承
java·开发语言
basketball61611 小时前
Go 语言从入门到进阶:4. 数组和MAP使用方法总结
开发语言·后端·golang
春生野草11 小时前
反射、Tomcat执行
java·开发语言