首页 > 其他分享 >猫映射(Arnold变换),猫脸变换介绍与基于例题脚本的爆破

猫映射(Arnold变换),猫脸变换介绍与基于例题脚本的爆破

时间:2024-11-18 11:18:32浏览次数:1  
标签:img 变换 image Arnold range arnold ori new 例题

前置信息
http://www.jiamisoft.com/blog/index.php/7249-erzhituxiangjiamisuanfaarnold.html
https://mp.weixin.qq.com/s/IbkAlyAPvbgMeNgqfwisTg
Arnold变换
Arnold变换是V.J.Arnold在遍历理论的研究中提出的一种变换,原意为catmapping,俗称猫脸变换。Arnold变换直观、简单、具有周期性,使用非常方便。Arnold变换的原理是先作x轴方向的错切变换,再作y轴方向的错切变换,最后的模运算相当于切割回填操作。
当对图像进行Arnold变换时,就是把图像的各个像素点位置按照下列公式进行移动,

从而得到一个相对原图像比较混乱的图像。对图像每进行一次Arnold变换,就相当于对该图像进行了一次置乱,一般来说这一过程需要反复进行多次才能达到令人满意的效果。利用Arnold变换对图像进行置乱后,使原本有意义的图像变成了像白噪声一样无意义的图像,从而实现了信息的初步隐藏。同时置乱次数可以作为水印系统的密钥,从而进一步增强系统的安全性和保密性。

Arnold变换也是具有周期性的。F.J.Dyson和H.Falk在分析离散Arnold变换的周期性时,给出了这样的结论:对于任意的N>2,Arnold变换的周期L≤N2/2。这是迄今为止最好的结果。计算Arnold周期的方法,对于给定的自然数N>2,下式的Arnold变换周期M是使得它成立的最小自然数n。

反变换查看原文,就不多赘述了

基于pillow库的加密实现

from PIL import Image
def arnold(infile: str, outfile: str = None, a: int = 1, b: int = 1, shuffle_times: int = 1, reverse: bool = False) -> None:    
"""    
Arnold猫脸变换函数
    Parameters:        
infile - 输入图像路径        
outfile - 输出图像路径        
a - Anrold 变换参数        
b - Anrold 变换参数        
shuffle_times - 置乱次数        
reverse - 逆变换    
"""    
inimg = Image.open(infile)    
width, height = inimg.size    
indata = inimg.load()    
outimg = Image.new(inimg.mode, inimg.size)    
outdata = outimg.load()
    for _ in range(shuffle_times):        
        for x in range(width):            
           for y in range(height):                
                 if reverse:                   
                      nx = ((a * b + 1) * x - a * y) % width                    
                      ny = (y - b * x) % height                
                 else:                    
                      nx = (x + a * y) % width                    
                      ny = (b * x + (a * b + 1) * y) % height                
                     outdata[ny, nx] = indata[y, x]        
            outimg.save(outfile if outfile else "arnold_"+infile, inimg.format)
arnold("before.png", "encode.png", 9, 39, 1)
arnold("encode.png", "decode.png", 9, 39, 1, True)

2024鹏程杯

import numpy as np
import cv2

def arnold_decode(image, arnold_times):
    a = 7
    b = 35
    # 创建新的解码图像,初始化为全0,数据类型为uint8
    decode_image = np.zeros(shape=image.shape, dtype=np.uint8)
    height, width = image.shape[0], image.shape[1]
    N = height  # N是正方形的边长
    for _ in range(arnold_times):  # 进行arnold_times次变换
        for old_x in range(height):
            for old_y in range(width):
                # 计算新的像素坐标
                new_x = ((a * b + 1) * old_x + (-a) * old_y) % N
                new_y = ((-b) * old_x + old_y) % N
                decode_image[new_x, new_y, :] = image[old_x, old_y, :]
    # 保存解码后的图像,确保图像保存成功
    try:
        cv2.imwrite('flag.png', decode_image, [int(cv2.IMWRITE_PNG_COMPRESSION), 0])  # 以PNG格式保存图像
        print("解码图像已保存为 flag.png")
    except Exception as e:
        print(f"保存图像时发生错误: {e}")
    return decode_image

if __name__ == '__main__':
    # 读取图像并确保图像加载成功
    image = cv2.imread('4.jpg')
    if image is not None:
        arnold_decode(image, 1)  # 此处arnold_times设置为1
    else:
        print("图像加载失败,请检查文件路径。")

2024源鲁杯CTFMisc


    image = np.array(image)
    arnold_image = np.zeros(shape=image.shape, dtype=image.dtype)
    h, w = image.shape[0], image.shape[1]
    N = h
    for _ in range(shuffle_times):
        for ori_x in range(h):
            for ori_y in range(w):
                new_x = (1*ori_x + b*ori_y)% N
                new_y = (a*ori_x + (a*b+1)*ori_y) % N
                if mode == '1':
                    arnold_image[new_x, new_y] = image[ori_x, ori_y]
                else:
                    arnold_image[new_x, new_y, :] = image[ori_x, ori_y, :]
    return Image.fromarray(arnold_image)

import numpy as np
from PIL import Image

def arnold_decode(image, shuffle_times=10, a=1, b=1, mode='1'):
    image = np.array(image)
    decode_image = np.zeros(shape=image.shape, dtype=image.dtype)
    h, w = image.shape[0], image.shape[1]
    N = h
    for _ in range(shuffle_times):
        for ori_x in range(h):
            for ori_y in range(w):
                new_x = ((a*b+1)*ori_x + (-b)* ori_y)% N
                new_y = ((-a)*ori_x + ori_y) % N
                if mode == '1':
                    decode_image[new_x, new_y] = image[ori_x, ori_y]
                else:
                    decode_image[new_x, new_y, :] = image[ori_x, ori_y, :]
    return Image.fromarray(decode_image)

img = Image.open('flag.png')
decode_img = arnold_decode(img)
decode_img.save('flag-output.png')

2024源鲁杯CTFCrypto

import matplotlib.pyplot as plt
import cv2
import numpy as np
from PIL import Image
def de_arnold(img,shuffle_time,a,b):
    r, c, d = img.shape
    dp = np.zeros(img.shape, np.uint8)

    for s in range(shuffle_time):
        for i in range(r):
            for j in range(c):
                x = ((a * b + 1) * i - b * j) % r
                y = (-a * i + j) % c
                dp[x, y, :] = img[i, j, :]
        img = np.copy(dp)
    cv2.imwrite(f"flag.png",img)

img_en = cv2.imread('en_flag.png')
de_arnold(img_en, 3,6, 9)

0xGame2024Misc

from PIL import Image
​
img = Image.open('mijiha.png')
if img.mode == "P":
    img = img.convert("RGB")
assert img.size[0] == img.size[1]
dim = width, height = img.size
​
st = 1
a = 35
b = 7
for _ in range(st):
    with Image.new(img.mode, dim) as canvas:
        for nx in range(img.size[0]):
            for ny in range(img.size[0]):
                y = (ny - nx * a) % width
                x = (nx - y * b) % height
                canvas.putpixel((y, x), img.getpixel((ny, nx)))
canvas.show()
canvas.save('flag.png')

了解这些比赛例题解密代码后
如果只知道啊a,b不知道翻转次数
那我们只有一个办法,爆破。
这是基于理解修改的一个爆破脚本

import os
from PIL import Image
import numpy as np

def arnold_decode(image, shuffle_times, a=, b=, mode='1'):
    image = np.array(image)
    decode_image = np.zeros(shape=image.shape, dtype=image.dtype)
    h, w = image.shape[0], image.shape[1]
    N = h
    for _ in range(shuffle_times):
        for ori_x in range(h):
            for ori_y in range(w):
                new_x = ((a*b+1)*ori_x + (-b)* ori_y) % N
                new_y = ((-a)*ori_x + ori_y) % N
                if mode == '1':
                    decode_image[new_x, new_y] = image[ori_x, ori_y]
                else:
                    decode_image[new_x, new_y, :] = image[ori_x, ori_y, :]
    return Image.fromarray(decode_image)

# 创建存储解码图片的文件夹
output_folder = "decoded_images"
os.makedirs(output_folder, exist_ok=True)

# 读取加密图片
img = Image.open('flag.png')

#最大翻转次数
max_attempts = 

# 开始爆破
for shuffle_times in range(1, max_attempts + 1):
    decoded_img = arnold_decode(img, shuffle_times=shuffle_times)
    decoded_img.save(os.path.join(output_folder, f"decoded_{shuffle_times}.png"))

print(f"所有尝试的解码图片已保存到文件夹: {output_folder}")
import os
import cv2
import numpy as np

def de_arnold(img, shuffle_time, a, b):
    r, c, d = img.shape
    dp = np.zeros(img.shape, np.uint8)

    for s in range(shuffle_time):
        for i in range(r):
            for j in range(c):
                x = ((a * b + 1) * i - b * j) % r
                y = (-a * i + j) % c
                dp[x, y, :] = img[i, j, :]
        img = np.copy(dp)
    return img

# 参数设置
a, b = ?,  ? # Arnold变换的参数
max_attempts = ? # 爆破的最大尝试次数
output_dir = "decrypted_images"  # 输出文件夹
os.makedirs(output_dir, exist_ok=True)

# 读取加密图片
img_en = cv2.imread('en_flag.png')
if img_en is None:
    raise FileNotFoundError("加密图片未找到,请检查路径和文件名是否正确。")

# 开始爆破
for shuffle_time in range(1, max_attempts + 1):
    img_decrypted = de_arnold(img_en, shuffle_time, a, b)
    output_path = os.path.join(output_dir, f"flag_{shuffle_time}.png")
    cv2.imwrite(output_path, img_decrypted)
    print(f"解密图片已保存: {output_path}")

print(f"爆破完成,共生成 {max_attempts} 张解密图片,保存在文件夹: {output_dir}")

这样我们就可以得到原图

标签:img,变换,image,Arnold,range,arnold,ori,new,例题
From: https://www.cnblogs.com/alexander17/p/18551089

相关文章

  • 二分查找 理论 例题
         递归代码intbinary_search(intarr[],intleft,intright,intkey){ if(left>right){//区间无效 return-1; } intmid=left+(right-left)/2;//直接平均可能会溢出 if(arr[mid]==key){ returnmid; }elseif(key>arr[mid]){ returnbinary_s......
  • opencv 之 图像处理与透视变换:从发票图片提取有效信息
    摘要在日常生活中,发票的处理是一项常见的任务。然而,由于拍摄角度、光线等因素的影响,直接从照片中提取发票信息往往存在困难。本文将介绍如何使用OpenCV库进行图像处理和透视变换,从而有效地从发票图片中提取有用信息。我们将通过一个具体的例子,展示如何从一张发票图片中提取出......
  • 小波变换+Transformer:融合创新驱动多领域进步
    2024发论文&模型涨点之——小波变换+Transformer小波变换(WaveletTransform,WT)和Transformer是两种强大的工具,它们在各自的领域内有着广泛的应用。小波变换是一种数学方法,用于分析信号的时间-频率特性,而Transformer则是一种深度学习模型,主要用于处理序列数据,特别是在自然语言......
  • css2D变换用法
    文章目录CSS2D变换详解与代码案例一、CSS2D变换的基本属性二、transform属性的使用三、变换原点的设置四、代码案例1.移动元素2.旋转元素3.缩放元素4.倾斜元素5.多重变换五、CSS2D变换的应用场景CSS2D变换详解与代码案例CSS2D变换是CSS3引入的一组功能......
  • 项目实战:Qt+OpenCV透视变换工具v1.1.0(支持打开图片、输出棋盘角点、调整偏移点、导出
    需求  1.打开图片;  2.矫正识别角点;  3.四点对应偏移距离;  4.支持设置棋盘格的行列角点数;  5.导出结果图片; 背景  深入研究图像拼接细分支算法,产出的效果查看工具,验证算法单步思路。 相关博客  《项目实战:Qt+OpenCV透视变换工具v1.1.0(支持打开图......
  • css3D变换用法
    文章目录CSS3D变换详解及代码案例一、CSS3D变换的基本概念二、3D变换的开启与景深设置三、代码案例CSS3D变换详解及代码案例CSS3D变换是CSS3中引入的一种强大功能,它允许开发者在网页上创建三维空间中的动画和交互效果。通过CSS3D变换,你可以实现元素的3D位移、旋转......
  • Matlab信号处理:连续小波变换
    小波变换是信号时频分析中浓墨重彩的一笔,本文将介绍连续小波变换(ContinuousWaveletTransform,CWT),对比短时傅里叶变换(STFT),CWT有更多的优势、更加灵活。区别于短时傅里叶变换的正弦基函数,连续小波变换采用小波基函数,通过调整小波基函数的尺度因子和时间平移因子,能分析信号在不......
  • 小D的abc变换问题-动态规划或者递归
    问题描述小D拿到了一个仅由 "abc" 三种字母组成的字符串。她每次操作会对所有字符同时进行以下变换:将 'a' 变成 'bc'将 'b' 变成 'ca'将 'c' 变成 'ab'小D将重复该操作 k 次。你的任务是输出经过 k 次变换后,得到的最终字符串。例如:对于初始字符串 "abc",执......
  • 栈和队列(原理、代码实现、例题)
    一、栈1.概念栈:一种特殊的线性表,其只允许在固定的一端进行插入和删除元素操作。进行数据插入和删除操作的一端称为栈顶,另一端称为栈底。栈中的数据元素遵守后进先出LIFO(LastInFirstOut)的原则。压栈:栈的插入操作叫做进栈/压栈/入栈,入数据在栈顶。出栈:栈的删除操作叫做......
  • Halcon刚性变换
       刚性仿射变换(RigidAffineTransformation)是一种机械视觉和图像处理常用的技术,通常用于在保持物体形状和大小不变的情况下,对物体进行旋转和平移。常见于模板匹配,定位跟随等场景。1:vector_angle_to_rigid(::Row1,Column1,Angle1,Row2,Column2,Angle2:HomMat......