当前位置: 首页 > news >正文

从JavaScript到Kotlin:移植Hilbert曲线图片混淆到安卓的经历

我把小番茄图片混淆做成了安卓App

为什么不用网页,非要做个App
用过“小番茄图片混淆”的人应该知道,这东西在贴吧、论坛传图的时候挺常见的。它的逻辑很简单:一张正常图片,点一下加密,就变成雪花屏一样的东西,别人看不懂原图;但拿着同样的算法,又能把雪花屏还原成原图。
听起来很实用对吧?

网站地址
https://ranzt.com/xiaofanqiehunxiao
网页版。每次想解一张图,流程是这样的:保存图片 → 打开浏览器 → 搜索“小番茄图片混淆” → 找到那个网站 → 上传图片 → 点解混淆。网站能打开还好,打不开就直接卡住。

所以我干脆做了一个安卓App,把小番茄的混淆算法搬到了手机上。所有处理都在本地跑,不上传,不联网,不需要每次去搜那个网页。

混淆到底在干什么
先搞清楚原理,不然代码没法写。
小番茄的核心是空间填充曲线,具体用的是Hilbert曲线。这东西说白了就是一条能“填满”整个二维平面的线,它会经过平面上的每一个点,而且每个点只经过一次。

混淆的过程其实就两步:
用Hilbert曲线把图片里所有像素的位置串成一串
把这一串像素整体偏移一定的步数,然后按偏移后的顺序重新排列

解密就是反向操作,把偏移的步数减回去。
因为每个像素的位置都变了,所以看起来像乱码;但位置变化的规律是固定的,所以能完全还原。这里有个关键点:小番茄做的是像素位置置乱,不是改变像素颜色值,所以还原后的图片质量跟原图完全一样,不会有压缩损失。
市面上有些混淆工具是做像素值变换的,那种还原后画质会下降,小番茄不会。

大概花了几天从拆解算法到打包成APK,断断续续大概两天。大部分时间不是在写代码,而是在解决“安卓为啥不让我直接存图片”这类问题。
把JavaScript改成Kotlin
网页版小番茄是用JavaScript写的,像素操作基于Canvas的ImageData。安卓这边用的是Bitmap,操作方式不太一样。
最大的区别在于:JavaScript的ImageData可以直接操作一个一维数组,通过索引访问像素;安卓的Bitmap需要用getPixel(x, y)和setPixel(x, y, color),按坐标访问。

把算法从JavaScript翻译成Kotlin,主要做了三件事:
生成Hilbert曲线坐标:这部分逻辑完全照搬,递归算法跟语言无关,直接用Kotlin重写
像素重排:JavaScript用数组索引,安卓换成坐标映射
批量读写优化:安卓的getPixel()单次调用开销不小,大图会慢。改成用getPixels()一次性读到数组里,处理完再用setPixels()写回去

核心代码大概长这样:
kotlin
// 生成Hilbert曲线坐标序列
val curve = generateHilbertCurve(order)

// 加密:按曲线偏移重排像素
for (i in curve.indices) {
val (x, y) = curve[i]
val (newX, newY) = curve[(i + offset) % curve.size]
pixels[newX][newY] = originalPixels[x][y]
}
适配安卓的几个关键点
算法移植本身不复杂,但让它在安卓上稳定跑起来,有几个地方需要专门处理。

1. 大图内存管理
Hilbert曲线需要操作整张图片的所有像素。一张手机拍的照片(4000x3000),如果完整加载到内存,光一个Bitmap就要占48MB。处理过程中还会创建新的Bitmap,内存峰值可能超过100MB,低端手机直接崩。
解决办法是做采样加载:处理时把图片缩放到合适尺寸(最长边不超过2048像素),这样内存占用降到原来的1/4左右。保存的时候再保存原始尺寸——因为算法操作的是像素位置,缩放后再还原会丢失细节,所以保存必须用原图。

2. 保存到相册的适配
Android 10 之后的分区存储,不能直接用文件路径在相册里创建文件了。必须用 MediaStore API,系统才会把图片纳入相册索引。
实现方式很简单:创建 ContentValues,指定文件名、MIME类型和存储路径,然后通过 ContentResolver 插入并写入数据。保存后图片会自动出现在相册的 Pictures/NoiseVault 文件夹里。

3. 异步处理避免卡界面
图片处理是CPU密集型操作,在Android主线程里跑几百毫秒以上就会掉帧,超过5秒会触发ANR(应用无响应)。
用协程把处理逻辑放到 Dispatchers.IO 线程池,主线程只负责更新UI。这样用户点击“加密”按钮后,界面不会卡死,进度反馈正常。
kotlin
viewModelScope.launch(Dispatchers.IO) {
val processed = processBitmap(originalBitmap)
withContext(Dispatchers.Main) {
previewImageView.setImageBitmap(processed)
}
}
4. 权限最小化
App只申请两个权限:读取存储和写入存储。不需要网络权限,不需要定位权限,不需要相机权限。用户安装的时候可以看到权限列表。
成品长什么样

App界面就一个页面:上面显示图片预览,中间是模式切换(加密/解密)和次数调节(1-99次),下面是三个按钮(选图、处理、保存)。
深色模式跟随系统,没有广告,不需要联网权限。整个安装包不到5MB。

关于核心算法内容
需要说明一下:小番茄基于空间填充曲线的混淆方案,在学术和开源领域已经存在很久了,并不是我发明的。我做的只是把网页版的实现方式移植到安卓本地,让用户可以在手机上离线使用,不用依赖网页和网络。

这个App里不包含原项目的任何代码、图片或品牌元素,只保留了算法实现。如果你在贴吧或论坛里收到小番茄混淆图,可以直接用这个App解,不用再开网页。

下载地址
源码和APK都在GitHub上:
https://github.com/Bologna-Zaicek/Tools-NoiseVault
Releases里有APK文件,下载安装后直接用。安装包不5MB,权限只有读取和保存图片。

http://www.jsqmd.com/news/1217222/

相关文章:

  • python学习(fifth)
  • 从零构建C++游戏框架:ECS架构、多线程渲染与性能优化实战
  • OpenAI自定义指令升级至5000字:打造持久化AI工作流指南
  • 现代系统登录模块设计与安全实践指南
  • Linux内核C语言编码规范详解与实践指南
  • c语言初学 | 数据类型、ASCII、转义字符、字符串
  • 基于YOLOv8的个人防具检测系统开发与实践
  • ROS工作空间与功能包创建指南:从入门到实践
  • 模型生产化落地:从Notebook到高可用ML服务的工程实践
  • Django认证系统实战:从基础到高级安全配置
  • AM62L EMIF控制器DFS与DFI时序寄存器配置实战指南
  • 缺失值处理不是填空题:从业务信号解码到工业级填充实战
  • Python if语句完全指南:从基础到进阶
  • Gson在Java中的JSON序列化与反序列化实践指南
  • FastAPI可观测性实战:用Prometheus+Grafana构建监控看板
  • 2026年7月最新亨得利官方服务项目及价格查询|网点地址与24小时客服热线权威信息公告 - 亨得利官方
  • Windows平台7款高效下载工具评测与优化指南
  • Nova Lake统一支持AVX-512:SIMD并行计算的技术突破与应用指南
  • 帕累托分布 密度函数
  • 2026年上海水磨石厂家优先考察的四个硬指标
  • 算术平均数的本质、陷阱与工程化应用指南
  • 多维聚合后数据操作:结构化、语义化与可追溯化实践
  • 在VMware上安装Ubuntu Desktop 26.04
  • C++小白记:string类用法
  • 土壤属性制图
  • Android项目迁移中的编码与资源问题排查指南
  • 开放式耳机哪款口碑好?2026年公认口碑好的开放式耳机推荐
  • 西安积家回收价格查询和靠谱回收平台实测排行(2026年7月最新) - 收的高名表回收平台
  • Python循环与函数定义的核心差异与应用技巧
  • HarmonyOS ArkUI Progress 进度条:5 种类型与动画演示