不是我說,這題一開始我是真的迷,第一:他說燈籠上是一對 字符,我原來還覺得這一對字符是密鑰和明文呢,直到我打開附件,這必然不是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); } }