不是我说,这题一开始我是真的迷,第一:他说灯笼上是一对 字符,我原来还觉得这一对字符是密钥和明文呢,直到我打开附件,这必然不是key啊:
这里你们能够看到,咱们的附件是这个模样,它多是明文也多是密文。回看上一道题,答案的格式是:cyberpeace{XXXX}这种格式,这说明啥呢?说明这个附件的大括号前是cyberpeace,而后大括号没有被加密或者解密,这说明这个算法不能管大括号。再加这个题的标题:Caesar,说明是凯撒算法。咱们知道凯撒加密算法是一种古典对称加密算法,须要一个密钥key做为移位的步长,但是这个题的密钥呢?咱们晓得答案的格式应该是cyberpeace这种款式,那么第一个字符相比:‘o’ - ‘c’ = 12
因而这个移位须要对每一个字符向后退12个步长(循环移动)。php
解决方案:
Caesar加密算法为: C = E(k, p) = (p + k) mod 26
Caesar解密算法为: p = D(k, C) = (C - k) mod 26java
根据上面的观察,获得须要倒退key = 12,因而这是解密,代码以下:算法
public class Caesar { static String src = "oknqdbqmoq{kag_tmhq_xqmdzqp_omqemd_qzodkbfuaz}"; public static void main(String[] args) { StringBuffer ans = new StringBuffer(""); for(int i = 0;i < src.length();++i) { if(src.charAt(i) >= 'a' && src.charAt(i) <= 'z') { char iChar = (char)((src.charAt(i) - 'a' - 12 + 26) % 26 + 'a'); ans.append(iChar); } else ans.append(src.charAt(i)); } System.out.println(ans); } }
这个题打开后的附件是:拿到这一串01串,原本我想的是二进制而后对照ASCii码……而后看到题目的标题:Morse,说明是莫斯密码。实话实说,我也没学过Morse密码,而后就去学了一下,看到了这个Morse密码对照表:markdown
而后咱们可看到这个Morse密码的密文对照是由:’-’ 和 ‘.’ 组成,咱们的附件上是0和1,那究竟是哪一种对应方式呢?咱也不知道,可是咱们知道最后明文的格式是cyberpeace开头的。咱们来看一下,开头第一个是11,这个应该对应字符 ‘c’,首先这个密文key的长度是2,惋惜这个密码表上的长度为2,且字符相同(毕竟11是俩相同字符)的对照只有:M……难道这把解出来的不是cyberpeace开头???
可是这样至少咱们肯定了一点,1对应 ‘-’,0对应’ .’app
import java.util.HashMap; import java.util.Map.Entry; import java.util.Set; public class Morse { static String src = "11 111 010 000 0 1010 111 100 0 00 000 000 111 00 10 1 0 010 0 000 1 00 10 110"; public static void main(String[] args) { src = src.replace('1', '-'); src = src.replace('0', '.'); HashMap<String, String> mp = new HashMap<>(); mp.put("a", ".-"); mp.put("b", "-..."); mp.put("c", "-.-."); mp.put("d", "-.."); mp.put("e", "."); mp.put("f", "..-."); mp.put("g", "--."); mp.put("h", "...."); mp.put("i", ".."); mp.put("j", ".---"); mp.put("k", "-.-"); mp.put("l", ".-.."); mp.put("m", "--"); mp.put("n", "-."); mp.put("o", "---"); mp.put("p", ".-"); mp.put("q", "--.-"); mp.put("r", ".-."); mp.put("s", "..."); mp.put("t", "-"); mp.put("u", "..-"); mp.put("v", "...-"); mp.put("w", ".--"); mp.put("x", "-..-"); mp.put("y", "-.--"); mp.put("z", "--.."); mp.put("0", "-----"); mp.put("1", ".----"); mp.put("2", "..---"); mp.put("3", "...--"); mp.put("4", "....-"); mp.put("5", "....."); mp.put("6", "-...."); mp.put("7", "--..."); mp.put("8", "---.."); mp.put("9", "----."); HashMap<String, String> MorseDec = new HashMap<>(); Set<Entry<String, String> > entrySet = mp.entrySet(); for(Entry<String, String> entry : entrySet) MorseDec.put(entry.getValue(), entry.getKey()); StringBuffer StrTemp = new StringBuffer(""); StringBuffer ans = new StringBuffer(""); for(int i = 0;i < src.length();++i) { if(' ' == src.charAt(i)) { ans.append(MorseDec.get(StrTemp.toString())); StrTemp = new StringBuffer(""); } else StrTemp.append(src.charAt(i)); } ans.append(MorseDec.get(StrTemp.toString())); System.out.println(ans); } }
计算出结果:
而后必定要记得按照他说的格式,答案就是:ide
首先是拿到附件,看了一下,那叫一个复杂:
首先看看,这是尼玛呢……可是大伙还记得上一篇密码学博客吗?咱们讲base64加密的时候,说到了不足6位的日后面补一组0,而后彻底由补出的0组成的6位编码表明字符 ‘=’ ,这里最后面有俩等号,这提示了咱们是否是应该用base64解密呢?这个好长啊,咱们来试试看(好在昨天写了Java程序):
程序跑出来是这么一大堆的东西,搞得我有点烦哦!可是我们看一下,貌似这些数字有规律啊!若是是ASCii码那就太好了,可是定睛一看,题目说答案都是小写字母……但是这些在ASCii码里早就突破了小写字母的范围了(97-122)上网查才晓得原来这是Unicode编码……话说Unicode编码有啥特征啊,届时我啷个晓得是哪一种编码格式哦!工具
Unicode编码:它前128个字符就是ASCII码,以后是扩展码。在Unicode码中,各个字符块基于一样的标准。而汉文,韩语,日语的象形文字占用从0X3000到0X9FFF的代码。
既然咱们得到了Unicode编码转成的ASCii编码,那咱们就继续看看呗……咋仍是这么长的密文……
继续试试base64进行二次解密:
咱们能够看到,这个数字貌似……和咱们ASCii码对应的小写字母相对于啊!
继续解析这个ASCii码:
不是我说,综合题属实仍是有点难的,对于我这种CTF小白来讲……可是获得Flag就好啦!
最终获得答案:
cyberpeace{welcometoattackanddefenceworld}编码
import java.util.Base64; public class base64 { static String src = "JiM3NjsmIzEyMjsmIzY5OyYjMTIwOyYjNzk7JiM4MzsmIzU2OyYjMTIwOyYjNzc7JiM2ODsmIzY5OyYjMTE4OyYjNzc7JiM4NDsmIzY1OyYjNTI7JiM3NjsmIzEyMjsmIzEwNzsmIzUzOyYjNzY7JiMxMjI7JiM2OTsmIzEyMDsmIzc3OyYjODM7JiM1NjsmIzEyMDsmIzc3OyYjNjg7JiMxMDc7JiMxMTg7JiM3NzsmIzg0OyYjNjU7JiMxMjA7JiM3NjsmIzEyMjsmIzY5OyYjMTIwOyYjNzg7JiMxMDU7JiM1NjsmIzEyMDsmIzc3OyYjODQ7JiM2OTsmIzExODsmIzc5OyYjODQ7JiM5OTsmIzExODsmIzc3OyYjODQ7JiM2OTsmIzUwOyYjNzY7JiMxMjI7JiM2OTsmIzEyMDsmIzc4OyYjMTA1OyYjNTY7JiM1MzsmIzc4OyYjMTIxOyYjNTY7JiM1MzsmIzc5OyYjODM7JiM1NjsmIzEyMDsmIzc3OyYjNjg7JiM5OTsmIzExODsmIzc5OyYjODQ7JiM5OTsmIzExODsmIzc3OyYjODQ7JiM2OTsmIzExOTsmIzc2OyYjMTIyOyYjNjk7JiMxMTk7JiM3NzsmIzY3OyYjNTY7JiMxMjA7JiM3NzsmIzY4OyYjNjU7JiMxMTg7JiM3NzsmIzg0OyYjNjU7JiMxMjA7JiM3NjsmIzEyMjsmIzY5OyYjMTE5OyYjNzc7JiMxMDU7JiM1NjsmIzEyMDsmIzc3OyYjNjg7JiM2OTsmIzExODsmIzc3OyYjODQ7JiM2OTsmIzExOTsmIzc2OyYjMTIyOyYjMTA3OyYjNTM7JiM3NjsmIzEyMjsmIzY5OyYjMTE5OyYjNzc7JiM4MzsmIzU2OyYjMTIwOyYjNzc7JiM4NDsmIzEwNzsmIzExODsmIzc3OyYjODQ7JiM2OTsmIzEyMDsmIzc2OyYjMTIyOyYjNjk7JiMxMjA7JiM3ODsmIzY3OyYjNTY7JiMxMjA7JiM3NzsmIzY4OyYjMTAzOyYjMTE4OyYjNzc7JiM4NDsmIzY1OyYjMTE5Ow=="; static String NextSrc = "LzExOS8xMDEvMTA4Lzk5LzExMS8xMDkvMTAxLzExNi8xMTEvOTcvMTE2LzExNi85Ny85OS8xMDcvOTcvMTEwLzEwMC8xMDAvMTAxLzEwMi8xMDEvMTEwLzk5LzEwMS8xMTkvMTExLzExNC8xMDgvMTAw"; public static void main(String[] args) { /* 加密 */ // String Encode = Base64.getEncoder().encodeToString(src.getBytes()); // System.out.println(Encode); /* 解密 */ byte[] Decode1 = Base64.getDecoder().decode(src); System.out.println(new String(Decode1)); /* 二次解密 */ byte[] Decode2 = Base64.getDecoder().decode(NextSrc); String ansAscii = new String(Decode2); System.out.println(ansAscii); // String dec2 = Decode1.toString(); // byte[] Decode2 = Base64.getDecoder().decode(dec2); // System.out.println(new String(Decode2)); StringBuffer Temp = new StringBuffer(""), res = new StringBuffer(""); for(int i = 0;i < ansAscii.length();++i) { if('/' == ansAscii.charAt(i) && 0 != i) { int resTemp = Integer.parseInt(Temp.toString()); res.append((char)(resTemp)); Temp = new StringBuffer(""); } else if('0' <= ansAscii.charAt(i) && ansAscii.charAt(i) <= '9') Temp.append(ansAscii.charAt(i)); } int resTemp = Integer.parseInt(Temp.toString()); res.append((char)(resTemp)); System.out.println(res); } }