维吉尼亚密码详解及C语言实现

18 篇文章 1 订阅

维吉尼亚密码详解及C语言实现


在这里插入图片描述

图片地址:https://bkimg.cdn.bcebos.com/pic/3ac79f3df8dcd100d56d833d748b4710b9122f3c?x-bce-process=image/watermark,image_d2F0ZXIvYmFpa2U4MA==,g_7,xp_5,yp_5/format,f_auto

0x01 维吉尼亚密码

这么“炫酷”的表格就是维吉尼亚密码,先看一下百度百科的介绍:
“维吉尼亚密码(又译维热纳尔密码)是使用一系列凯撒密码组成密码字母表的加密算法,属于多表密码的一种简单形式。”

吉奥万·巴蒂斯塔·贝拉索,意大利密码学家。他的主要著作是于1553年出版的《吉奥万·巴蒂斯塔·贝拉索先生的密码》(La cifra del. Sig. Giovan Battista Bellaso)。
贝拉索1505年出生于一个显赫的家庭。他的父亲是皮尔文森佐(Piervincenzo),是布雷西亚的一位贵族,从15世纪起就在镇上和卡普里亚诺(Capriano)郊区拥有一处房产,位于一个叫做Fenili Belasi(贝拉索的谷仓)的社区,包括圣三一教堂。牧师每年得到一笔固定的薪金和一些柴火。家族的纹章是“在蓝色的田野上三个红舌金狮子头在侧面”。
贝拉索精通研究,擅长数学,在当时这种艺术在所有的意大利宫廷,主要是在罗马教廷享有极大的赞赏。在密码学历史的黄金时期,他只是众多秘书中的一个,他们出于对知识的热爱或真正的需要,在日常活动中尝试新的系统。他的密码标志着一个时代,被认为是四个世纪以来破解不了的。

在这里插入图片描述

吉奥万·巴蒂斯塔·贝拉索是第一个提出多表密码概念的人,但是后来被误认为是布莱斯·德·维吉尼亚所发明,所以也就称之为维吉尼亚密码

0x02 维吉尼亚密码原理

在这里插入图片描述

这一一张维吉尼亚的表,可以清楚的看到,这张表由26行,每一行都由前一行字母的顺序向左偏移一位得到

明文为:
VIRGINIACIPHER

密钥为:
SECRETKEY

表格的行代表密钥,列代表明文
明文第1个:V
密文第1个:S 对应密文:N
明文第2个:I
密文第2个:E 对应密文:M
明文第3个:R
密文第3个:C 对应密文:T
明文第4个:G
密文第4个:R 对应密文:X

最后结果为:NMTXMGSEAATJVV
注意:维吉尼亚密码在线加密/解密工具只对字母进行加密,不区分大小写,若文本中出现非字母字符会原样保留!!所以在CTF比赛中可以通过这个很快速的判断出维吉尼亚密码

0x03 维吉尼亚密码CTF题目

题目名称:Ranma½
在这里插入图片描述

一开始并无思路只知道是一个日本动画片,其中的编码方式如下
在这里插入图片描述

用sublime打开,看到最后应该是flag
在这里插入图片描述

再重复一遍重点:维吉尼亚密码在线加密/解密工具只对字母进行加密,不区分大小写,若文本中出现非字母字符会原样保留

在这里插入图片描述

逆推思路其实也不难,在不知道维吉尼亚密码的时候应该怎么解?

前面有一串10646-1,根据搜索知道是ISO/IEC 10646-1,根据ISO/IEC 10646-1内容,推测后面为UTF-8,并通过两个关键词找到原文

网址:https://datatracker.ietf.org/doc/html/rfc3629

在这里插入图片描述

原文:
ISO/IEC 10646-1 defines a large character set called the Universal Character Set (UCS) which encompasses most of the world’s writing systems. The originally proposed encodings of the UCS, however, were not compatible with many current applications and protocols, and this has led to the development of UTF-8, the object of this memo. UTF-8 has the characteristic of preserving the full US-ASCII range, providing compatibility with file systems, parsers and other software that rely on US-ASCII values but are transparent to other values.

仔细分析两端文字,发现相同的单词对应不同的密文,说明不是替换,并且根据大小写和一些线索也排除了换位密码

通过尝试得到两段的ascii分析,如下图:
在这里插入图片描述

根据相减得到的值,发现可能有循环

在这里插入图片描述

根据代码筛选出相减的值,得到循环规律
在这里插入图片描述

以此类推找到flag:TQLCTF{CODIN6_WOQ1D}

不过比赛的时候能省时间还是工具解决吧!

0x04 C语言实现

# -*- coding = utf-8 -*-
# @Time : 2022/2/24 9:03 上午
# @Author : lmn
# @File : Virginia.c
# @Software : CLion

#include <stdio.h>
#include <assert.h>
#define TEXT 100
#define TEXT 100
#define KEY 50

int CHOOSE()
{
    printf("*******************************\n");
    printf("*** 1. 加密  2. 解密  0. 退出****\n");
    printf("*******************************\n");
    int a = 0;
    scanf("%d",&a);
    return a;
}
//计算密文或明文字符长度长度
int TestLen(char* text){
    int sz = 0;
    for(sz=0;text[sz]!='\0';sz++);
    return sz;
}
//初始化
void InitVirginia(char* plaintext, char* ciphertext, char* key){
    int j = 0;
    for (j = 0; j < TEXT; j++) {
        plaintext[j] = ' ';
        ciphertext[j] = ' ';
    }
    for (j = 0; j < KEY; j++) {
        key[j] = ' ';
    }
}
//加密
int ENCODE(char* plaintext, char* key, char* result){
    assert(plaintext && key && result);

    //计算 plaintext 元素个数
    int sz = TestLen(plaintext);
    
    //计算key元素个数
    int sz2 = TestLen(key);

    int i = 0;
    for(i = 0 ; i < sz ; i++)
    {
        result[i] = (plaintext[i] + key[i % sz2] - 'a'-'a')%26 + 'a';
    }
    printf("\n加密后为:%s\n\n",result);
    return 0;
}
//解密
int DECODE(char* ciphertext, char* key, char* result){
    assert(ciphertext && key && result);

    //计算 ciphertext 元素个数
    int sz = TestLen(ciphertext);
    
    //计算key元素个数
    int sz2 = TestLen(key);

    int i = 0;
    for(i = 0 ; i < sz ; i++)
    {
        result[i] = (ciphertext[i] + 26 - key[i % sz2])%26 + 'a';
    }
    printf("\n解密后为:%s\n\n",result);
    return 0;
}
int main()
{
    char plaintext[TEXT] = {0};
    char ciphertext[TEXT] = {0};
    char key[KEY] = {0};
    // 1.选择进行的操作
    int a = 1;
    while(a)
    {
        a = CHOOSE();
        if (a == 0)
            break;
        InitVirginia(plaintext, ciphertext, key);
        switch (a) {
            case 1:
                //加密
                printf("请输入明文:>");
                scanf("%s",plaintext);
                printf("\n请输入密钥:>");
                scanf("%s",key);
                ENCODE(plaintext,key,ciphertext);
                break;
            case 2:
                //解密
                printf("请输入密文:>");
                scanf("%s",ciphertext);
                printf("\n请输入密钥:>");
                scanf("%s",key);
                DECODE(ciphertext, key,plaintext);
                break;

            default:
                printf("输入有误请重新输入!\n\n");
                
        }
    }
    return 0;
}

功能介绍:

  1. 加了初始化函数InitVirginia,可以循环对维吉尼亚密码进行加解密
  2. 防止功能过度繁杂,每次运算时需要计算长度,所以加入了计算长度的函数TestLen
  3. 防止数组为空,加入了断言
  4. C语言初学者可能有地方写的不标准,欢迎提出

维吉尼亚密码在线工具
https://www.dcode.fr/vigenere-cipher
http://www.atoolbox.net/Tool.php?Id=856

  • 4
    点赞
  • 50
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
大学生参加学科竞赛有着诸多好处,不仅有助于个人综合素质的提升,还能为未来职业发展奠定良好基础。以下是一些分析: 首先,学科竞赛是提高专业知识和技能水平的有效途径。通过参与竞赛,学生不仅能够深入学习相关专业知识,还能够接触到最新的科研成果和技术发展趋势。这有助于拓展学生的学科视野,使其对专业领域有更深刻的理解。在竞赛过程中,学生通常需要解决实际问题,这锻炼了他们独立思考和解决问题的能力。 其次,学科竞赛培养了学生的团队合作精神。许多竞赛项目需要团队协作来完成,这促使学生学会有效地与他人合作、协调分工。在团队合作中,学生们能够学到如何有效沟通、共同制定目标和分工合作,这对于日后进入职场具有重要意义。 此外,学科竞赛是提高学生综合能力的一种途径。竞赛项目通常会涉及到理论知识、实际操作和创新思维等多个方面,要求参赛者具备全面的素质。在竞赛过程中,学生不仅需要展现自己的专业知识,还需要具备创新意识和解决问题的能力。这种全面的综合能力培养对于未来从事各类职业都具有积极作用。 此外,学科竞赛可以为学生提供展示自我、树立信心的机会。通过比赛的舞台,学生有机会展现自己在专业领域的优势,得到他人的认可和赞誉。这对于培养学生的自信心和自我价值感非常重要,有助于他们更加积极主动地投入学习和未来的职业生涯。 最后,学科竞赛对于个人职业发展具有积极的助推作用。在竞赛中脱颖而出的学生通常能够引起企业、研究机构等用人单位的关注。获得竞赛奖项不仅可以作为个人履历的亮点,还可以为进入理想的工作岗位提供有力的支持。
维吉尼亚密码是一种基于多表替换密码的加密算法,它使用一个关键字和明文进行加密和解密。下面是使用C语言实现维吉尼亚密码的基本步骤: 1. 定义关键字:选择一个关键字作为加密和解密的密钥。关键字可以是任意长度的字符串,通常由字母组成。 2. 明文转换:将明文转换为数字,可以使用ASCII码将每个字符映射为对应的数字。 3. 关键字扩展:将关键字扩展为与明文长度相同的字符串。可以使用循环来实现关键字的扩展。 4. 加密/解密:将明文字符与关键字字符进行对应位置的加密/解密操作。加密操作可以通过将明文字符与关键字字符相加并取模得到密文字符。解密操作可以通过将密文字符与关键字字符相减并取模得到明文字符。 5. 密文转换:将加密后的数字转换回对应的字符,可以使用ASCII码将数字映射为对应的字符。 下面是一个简单的C语言实现维吉尼亚密码的示例代码: ```c #include <stdio.h> #include <string.h> void vigenereEncrypt(char* plaintext, char* keyword) { int plaintextLen = strlen(plaintext); int keywordLen = strlen(keyword); char ciphertext[plaintextLen + 1]; for (int i = 0; i < plaintextLen; i++) { ciphertext[i] = ((plaintext[i] - 'a' + keyword[i % keywordLen] - 'a') % 26) + 'a'; } ciphertext[plaintextLen] = '\0'; printf("Ciphertext: %s\n", ciphertext); } void vigenereDecrypt(char* ciphertext, char* keyword) { int ciphertextLen = strlen(ciphertext); int keywordLen = strlen(keyword); char plaintext[ciphertextLen + 1]; for (int i = 0; i < ciphertextLen; i++) { plaintext[i] = ((ciphertext[i] - 'a' - keyword[i % keywordLen] + 'a' + 26) % 26) + 'a'; } plaintext[ciphertextLen] = '\0'; printf("Plaintext: %s\n", plaintext); } int main() { char plaintext[] = "hello"; char keyword[] = "key"; vigenereEncrypt(plaintext, keyword); vigenereDecrypt("uryyb", keyword); return 0; } ``` 这段代码实现维吉尼亚密码的加密和解密功能。在示例中,明文为"hello",关键字为"key",加密后的密文为"uryyb",解密后的明文为"hello"。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

lmn_

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值