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;
}
相关推荐
LDR0069 天前
Type-C 快充全面升级!LDR6601 赋能个人护理便携电机,重塑剃须刀 / 理发器新体验
c语言·开发语言
雪碧聊技术9 天前
Tree.js是什么?一文讲透
开发语言·javascript·ecmascript
码云数智-园园9 天前
C++20 Modules 模块详解
java·开发语言·spring
swordbob9 天前
NIO的channel中什么是 fd(File Descriptor,文件描述符)
java·开发语言·nio
源分享9 天前
Java线程同步的多种实现方法(非常详细)
java·开发语言·jvm
Luminous.9 天前
C语言--day30
c语言·开发语言
玖玥拾9 天前
C/C++ 数据结构(七)栈、容器适配器
c语言·数据结构·c++··容器适配器
何以解忧,唯有..9 天前
Go语言循环语句详解:for、range与循环控制
开发语言·算法·golang
謓泽9 天前
C语言不是语法,是通往机器的地图。
c语言·开发语言
云水一下9 天前
从零开始学 PHP 系列(一):PHP 的前世今生与开发环境搭建
开发语言·php