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;
}
相关推荐
InfinteJustice1 小时前
踩坑分享C 语言文件操作全攻略:从基础读写到随机访问与缓冲区原理
c语言·开发语言·microsoft
码云数智-大飞1 小时前
滥用Lombok的@EqualsAndHashCode导致线上事故复盘
开发语言
yong99901 小时前
C# 实时查看硬件使用率(CPU 内存 硬盘 网络)
开发语言·网络·c#
不午休の野猫1 小时前
vs + qt环境编译.sln项目时报无法解析的外部符号metaObject && qt_metacast
开发语言·qt
吴声子夜歌2 小时前
Java——接口的细节
java·开发语言·算法
阿拉金alakin2 小时前
深入理解 Java 锁机制:CAS 原理、synchronized 优化与主流锁策略全总结
java·开发语言
myheartgo-on2 小时前
Java—方 法
java·开发语言·算法·青少年编程
雨落在了我的手上2 小时前
如何学习java?
java·开发语言·学习
神仙别闹3 小时前
基于 C# OpenPGP 的文件管理系统
开发语言·c#
番石榴AI3 小时前
纯 CPU 推理!0.1B 超轻量级端到端OCR模型,使用 Java 进行文档解析
java·开发语言·ocr