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;
}
相关推荐
CircleMouse2 小时前
springboot项目中使用Java 8的日期时间API
java·开发语言·spring boot·后端·spring
前端达人2 小时前
被JavaScript忽视的Web Animations API:为什么说它是前端动画的真正未来?
开发语言·前端·javascript·ecmascript
米羊1213 小时前
风险评估文档记录
开发语言·网络·php
摘星编程3 小时前
解锁Agent智能体的未来:五大实战策略彻底革新人机协作模式
java·开发语言
Aerkui3 小时前
Go 泛型(Generics)详解
开发语言·后端·golang
clive.li3 小时前
go-webmvc框架推荐
开发语言·后端·golang
寻寻觅觅☆3 小时前
东华OJ-基础题-127-我素故我在(C++)
开发语言·c++·算法
ab1515173 小时前
2.13完成101、102、89
开发语言·c++·算法