用python实现图像RGB通道分离,LSB 信息隐藏和信息提取,并且采用一种攻击手段攻击藏有信息的图像

python版本3.10

这段代码仅支持隐藏输入英文信息

默认注释了展示R、G、B三层的语句

请注意修改图片路径为你自己的图片所在路径

from PIL import Image


def get_pixel_values(image):
    width, height = image.size
    pixel_values = list(image.getdata())
    if image.mode == 'RGB':
        channels = 3
    elif image.mode == 'RGBA':
        channels = 4
    else:
        raise ValueError("不支持的图像模式: %s" % image.mode)
    pixel_values = [pixel_values[i * width:(i + 1) * width] for i in range(height)]
    return pixel_values, channels


def get_channel_image(pixel_values, channel):
    return [[pixel[channel] for pixel in row] for row in pixel_values]


def merge_channels(red_channel, green_channel, blue_channel, channels):
    pixels = []
    for i in range(len(red_channel)):
        row = []
        for j in range(len(red_channel[i])):
            if channels == 3:
                pixel = (red_channel[i][j], green_channel[i][j], blue_channel[i][j])
            else:
                pixel = (red_channel[i][j], green_channel[i][j], blue_channel[i][j], 255)
            row.append(pixel)
        pixels.append(row)
    return pixels


def hide_message(image, message):
    pixel_values, channels = get_pixel_values(image)
    red_channel = get_channel_image(pixel_values, 0)
    green_channel = get_channel_image(pixel_values, 1)
    blue_channel = get_channel_image(pixel_values, 2)

    message += "EOF"  # 为消息添加文件结束标记
    message_binary = ''.join(format(ord(i), '08b') for i in message)

    # 检查图像是否有足够的容量来隐藏消息
    max_message_length = len(red_channel) * len(red_channel[0]) * channels // 8
    if len(message_binary) > max_message_length:
        raise ValueError("Message too long to hide in image")

    # LSB算法
    index = 0
    for i in range(len(red_channel)):
        for j in range(len(red_channel[i])):
            if index < len(message_binary):
                red_channel[i][j] = (red_channel[i][j] & ~1) | int(message_binary[index])
                index += 1
            if index < len(message_binary):
                green_channel[i][j] = (green_channel[i][j] & ~1) | int(message_binary[index])
                index += 1
            if index < len(message_binary):
                blue_channel[i][j] = (blue_channel[i][j] & ~1) | int(message_binary[index])
                index += 1
            if index >= len(message_binary):
                break
        if index >= len(message_binary):
            break

    merged_pixels = merge_channels(red_channel, green_channel, blue_channel, channels)
    merged_image = Image.new(image.mode, image.size)
    merged_image.putdata([pixel for row in merged_pixels for pixel in row])

    return merged_image


def extract_message(image):
    pixel_values, channels = get_pixel_values(image)
    red_channel = get_channel_image(pixel_values, 0)
    green_channel = get_channel_image(pixel_values, 1)
    blue_channel = get_channel_image(pixel_values, 2)

    # LSB算法
    message_binary = ""
    message_hex = ""
    for i in range(len(red_channel)):
        for j in range(len(red_channel[i])):
            message_binary += str(red_channel[i][j] & 1)
            if len(message_binary) % 8 == 0:
                message_hex += '{:02x}'.format(int(message_binary[-8:], 2))
            if message_binary[-8:] == "00000000":
                return bytes.fromhex(message_hex).decode('utf-8', 'ignore')
                message_hex += '{:02x}'.format(int(message_binary[-8:], 2))
            message_binary += str(green_channel[i][j] & 1)
            if len(message_binary) % 8 == 0:
                message_hex += '{:02x}'.format(int(message_binary[-8:], 2))
            message_binary += str(blue_channel[i][j] & 1)
            if len(message_binary) % 8 == 0:
                message_hex += '{:02x}'.format(int(message_binary[-8:], 2))

    return bytes.fromhex(message_hex).decode('gbk')


def attack_image(image):
    # 随机改变每个像素的最后一位
    pixel_values, channels = get_pixel_values(image)
    for i in range(len(pixel_values)):
        for j in range(len(pixel_values[i])):
            pixel = list(pixel_values[i][j])
            for k in range(channels):
                pixel[k] ^= 1
            pixel_values[i][j] = tuple(pixel)
    image_attacked = Image.new(image.mode, image.size)
    image_attacked.putdata([pixel for row in pixel_values for pixel in row])
    return image_attacked


# 加载图像  <----注意在这里需要你自行设置图片路径!---->
image = Image.open("image_path")

# 分离RGB三层图像并展示
red_channel_image = Image.new("L", image.size)
red_channel_image.putdata([pixel[0] for row in image.getdata() for pixel in [row]])
# red_channel_image.show()

green_channel_image = Image.new("L", image.size)
green_channel_image.putdata([pixel[1] for row in image.getdata() for pixel in [row]])
# green_channel_image.show()

blue_channel_image = Image.new("L", image.size)
blue_channel_image.putdata([pixel[2] for row in image.getdata() for pixel in [row]])
# blue_channel_image.show()

# 将信息隐写入图像
message = "This is a secret message"
steg_image = hide_message(image, message)
steg_image.show()

# 从示例图像中提取信息

extracted_message = extract_message(steg_image)
print("提取到信息: " + extracted_message)

# 攻击示例图像
attacked_image = attack_image(steg_image)
attacked_image.show()

# 检查是否能从被攻击图像中获取信息
try:
    extracted_message = extract_message(attacked_image)
    print("从被攻击图像中提取到信息: " + extracted_message)
except:
    print("未能从被攻击图像中提取到信息")

  • 1
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值