解密:粽子的密码
两天前的这次粽子红包解密活动受到了许多读者的关注,许多读者都在询问解题方法。
活动回顾:我打赌!90%程序员都破解不了这个粽子,不信你试!
如今所有红包都已经领完了,今天就来解答一下一下通关方法。
第一关
入口是这张粽子图片:
稍微仔细一点看就能看到左边有一个二维码:
够明显的了吧?话说当初我想调得更淡一点,直到肉眼看不出来,不过想了想还是让大家都能发现,这样参与的人才积极。
不过二维码虽然发现了,很多人后台留言说扫不出来,那是自然,如果这样直接就扫出来了,那还算是一个关卡吗?想扫描出来还是需要费点功夫的!
最直接的想法就是用PS调整图片的色阶、颜色通道值等等手段,把二维码对比加深,直到能够扫描出来位置。
这里推荐一个在线的PS工具,简单轻便,绝大部分日常用到的功能都覆盖了,不需要再单独去装一个PhotoShop,费时费力
https://www.uupoop.com/
当然这里PS操作不只一种方式,这里只举一种方法
打开图片,通过调整图片
先进行反向:
接着进行黑白调整,直到可以清晰看到二维码:
扫描即可得到第一关的口令和下一关的入口:
第二关
上面得到的第二关是一个URL:
https://static01.imgkr.com/temp/a9032397b67b4ecf919cd0e1db5c764e.png
浏览器中打开它,看到的是一个满是字符的png图片:
一眼就可以看出这肯定是经过什么编码算法处理过的,可以从常用的编码算法来进行尝试解码。继续观察字符特征,可以基本判断就是base64编码!
不过想要解码的前提是得拿到这一段字符文本,现在摆在面前的是一张图片,如何把图片中的字符提取出来呢?
这一关的关键就是这里!
从图片中提取文本,自然就是OCR技术了!
找一找在线的OCR服务,基本都会面临一个问题就是:
- 0 和 O
- 1 和 l
- w 和 vv
绝大多数的OCR服务都无法完美的区分这三种情况,所以在OCR帮我们完成了主要工作后,还需要手动来校验,所以这里还需要考验一下大家的细心和耐心。
当然如果你不去校验的话,直接拿着OCR识别的结果去base64解码,也能拿到第二关的口令:
第三关
第二关解码的结果中,除了有第二关的口令以外,还有另一段编码内容。
这里需要强调的是:如果在第二关中的OCR识别结果没有做校验,那么解码得到的内容就会出错,也将会影响到第三关的解题。
这一段编码又是一层base64编码,你说我怎么知道是base64?
首先,base64是最常用的编码算法,所以首先应该尝试它,如果不对再想其他编码算法。
其次,观察编码串出现的字符,base64就是26个英文字符的大小写共计52个、10个阿拉伯数字、加号+、斜杠/,共计64个字符。
那不对啊,前面的图片中有等于号=出现呢,注意,这也就是base64的一个非常重要的特征,具体原因可以看一下base64编码方式,总之记住,如果出现只有上面64个字符的情况,再如果结尾还有等号出没的情况下,基本上就是base64没跑了。
当然除了base64还有很多变种,比如base85、base92、base128等众多算法。
将第二关解码的这一串字符串,再次解码:
这次发现,左边乱码了!!!
再观察,开头出现了PNG三个特征字符,有理由怀疑,这是一个PNG图片的编码结果。
打开Python,六行代码,将解码的结果写成一个后缀为png的图片文件:
import base64
content = 'iVBORw0KGgoAAAANSUhEUg···' # 省略完整字符串
decodeContent = base64.b64decode(content)
fo = open("3.png", "w")
fo.write(decodeContent)
fo.close()
打开生成的文件,第三关的口令随之揭晓:
而这个最终关的口令,其实一直都在文章的这张图中:
总结
这一次端午节游戏,没想到大家热情都挺高的,这有点出乎我的意料,感谢大家的捧场支持。
本次活动只是牛刀小试,不久之后的关注破万活动,更多有趣的玩法,更加刺激的套路,更加多元的技术知识,更加心动的红包将向你砸来,期待大家的继续支持和参与!
- 区块链学堂——公有链、私有链、联盟链、侧链、互联链
- 人工智能将让我们更擅长辩论
- ASP.NET路由系统实现原理:HttpHandler的动态映射
- 腾讯、卓健科技、恩泽医疗合力打造“互联网+智慧医院”
- 区块链,不是比特币(1)
- 小程序缓存 删不删你都该知道的事儿
- 32位 or 64位:Apache CloudStack系统VM架构选择
- Apache CloudStack系统VM架构选择
- ASP.NET MVC Controller激活系统详解:IoC的应用[下篇]
- 使用Docker的Alluxio群集设置
- 通过重建Hosting系统理解HTTP请求在ASP.NET Core管道中的处理流程[中]:管道如何处理请求
- ASP.NET MVC Model元数据及其定制: 初识Model元数据
- 如何在企业中融入机器学习
- How ASP.NET MVC Works?
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- 详解Ubuntu环境下部署Django+uwsgi+nginx总结
- 如何从Node.js中的命令行读取输入
- pyqt5中动画的使用详解
- PyQt使用QPropertyAnimation开发简单动画
- 如何使用JavaScript漂亮地打印JSON对象
- Android使用AsyncTask加载图片的操作流程
- nodejs中post请求方式,req.body接值为空如何解决
- Kotlin使用静态变量与静态方法详解
- Android通过代码控制ListView上下滚动的方法
- Android为Tiny4412设备驱动在proc目录下添加一个可读版本信息的文件
- Android Studio 4.1 发布啦
- Spring Boot 2.4 配置文件将加载机制大变化
- 「性能提升」扩展 Spring Cache 支持多级缓存
- OAuth 2.0 单元测试解决方案
- 聊一聊如何搭建高性能网站哪一些事