Misc知识集

yolo 发布于 2024-12-08 84 次阅读


这里是记录下平时遇到的知识小点,积少成多嘛

LSB&MSB

LSB和MSB是常见的隐写类型,前者是最低位,后者是最高位

两种隐写很类似的,方法也很通用,这里我就记载些通解了

通解一

使用StegSolve神器,真的越往后越能感觉到它的好用

在Data Extract中,我们可以灵活选择分离数据,比如说,如果是LSB隐写,这样选

如果是MSB隐写,这样选

这些就已经很强了,但是Stegsolve真不会让我们失望

举个例子,我有张照片被MSB隐写了,这时候需要我将隐写信息导出来,最直接的方法就是用这个神器直接导出即可,选好我们要的模式,点击save bin就行

当然还有其他的方法,也算个通解吧,请看通解二。

通解二

这个方法不是很轻松的哦,通过脚本来分离我们要的数据,当然,这里面肯定涉及相关的数学知识,有兴趣的话,自行百度吧

MSB

先看那个MSB隐写,我们清楚的是,要将最高层的数据按照RGB模式(我的这道题是这样的,因题而异

import argparse
from PIL import Image
import numpy as np
import os
​
def extract_bits_from_image(image_path):
    # 打开图像并转换为 NumPy 数组
    img = Image.open(image_path)
    pixels = np.array(img)
    
    # 存储提取的比特
    bit_string = ''
    
    # 遍历每个像素,每个颜色通道(R, G, B)提取最高有效位
    for i in range(pixels.shape[0]):
        for j in range(pixels.shape[1]):
            for k in range(pixels.shape[2]):
                bit_string += str((pixels[i, j, k] >> 7) & 1)  # 提取最高有效位
    
    return bit_string
​
def bits_to_file(bit_string, output_file_path):
    # 将比特流转换为字节流,并写入文件
    byte_array = bytearray()
    for i in range(0, len(bit_string), 8):
        byte = bit_string[i:i+8]
        byte_array.append(int(byte, 2))
    
    # 将字节流写入文件
    with open(output_file_path, 'wb') as file:
        file.write(byte_array)
    print(f"Extracted bits written to {output_file_path}")
​
def main():
    # 设置命令行参数解析
    parser = argparse.ArgumentParser(description="Extract hidden data from an image.")
    parser.add_argument('-f', '--file', required=True, help="The image file to extract data from.")
    args = parser.parse_args()
​
    image_path = args.file  # 获取输入图像文件路径
    
    # 检查文件是否存在
    if not os.path.exists(image_path):
        print(f"Error: The file '{image_path}' does not exist.")
        return
    
    # 获取文件名并生成输出文件路径
    output_file_path = os.path.splitext(image_path)[0] + '.extracted'
    
    # 从图像中提取比特流
    bit_string = extract_bits_from_image(image_path)
​
    # 将提取的比特流保存为文件
    bits_to_file(bit_string, output_file_path)
​
if __name__ == "__main__":
    main()
​

使用方法是python msb.py -f xxx.png

!温馨提示,不管是通解一还是通解二,得到的数据在010中查看都会在后面发现很多的0,这些0都是没有被加密的数据,为了后面的操作正常进行,还是建议将那些0都给删去

ok,接下来就是LSB了

LSB

import os
import argparse
from PIL import Image
​
# 从图片中提取隐藏的二进制数据
def extract_lsb(image_path):
    # 打开图像文件
    img = Image.open(image_path)
    # 获取图像的像素数据
    pixels = img.load()
    
    binary_data = ''
    for y in range(img.height):
        for x in range(img.width):
            # 获取每个像素的 RGB 值
            r, g, b = pixels[x, y]
            # 提取 RGB 中的最低有效位
            binary_data += str(r & 1)  # 红色通道的最低有效位
            binary_data += str(g & 1)  # 绿色通道的最低有效位
            binary_data += str(b & 1)  # 蓝色通道的最低有效位
            
    # 以8位为一组,转换成字节
    byte_data = bytearray()
    for i in range(0, len(binary_data), 8):
        byte_data.append(int(binary_data[i:i+8], 2))
    
    return byte_data
​
# 将提取的字节数据保存为文件
def save_extracted_data(binary_data, output_file):
    with open(output_file, 'wb') as f:
        f.write(binary_data)
​
# 自动生成输出文件名(添加 ".decode" 后缀)
def get_output_filename(input_file):
    # 获取文件名(不带扩展名)
    file_name, file_extension = os.path.splitext(input_file)
    # 生成新的文件名,加上 ".decode" 后缀
    return f"{file_name}.decode"
​
# 解析命令行参数
def parse_args():
    parser = argparse.ArgumentParser(description="LSB 隐写解密工具")
    parser.add_argument('-f', '--file', type=str, required=True, help="指定要解密的图像文件")
    return parser.parse_args()
​
# 主程序
def main():
    args = parse_args()  # 获取命令行参数
    input_image = args.file  # 获取输入文件路径
    
    # 生成输出文件路径
    output_file = get_output_filename(input_image)
    
    # 提取数据并保存
    binary_data = extract_lsb(input_image)
    save_extracted_data(binary_data, output_file)
    
    print(f'隐写数据已提取并保存为 {output_file}')
​
if __name__ == '__main__':
    main()
​
​

使用方法是python LSB.py -f xxx.png

都到这里了,不如整整LSB和MSB隐写脚本?算了,等我有空了再加上吧