基于生命游戏的hash函数改进(续2)

生命游戏(conway game of life, Conway life game)简介

在康威的生命游戏中,规定了如下生存定律:

  1. 当前细胞为死亡状态时,当周围有3个存活细胞时,则迭代后该细胞变成存活状态(模拟繁殖);若原先为生,则保持不变。
  2. 当前细胞为存活状态时,当周围的邻居细胞低于两个(不包含两个)存活时,该细胞变成死亡状态(模拟生命数量稀少)。
  3. 当前细胞为存活状态时,当周围有两个或3个存活细胞时,该细胞保持原样。
  4. 当前细胞为存活状态时,当周围有3个以上的存活细胞时,该细胞变成死亡状态(模拟生命数量过多)。

生命游戏制作哈希(hash)函数的问题

重复性

在经过几轮的迭代之后,这个图像稳定,并且开始出现规律性。

信息损失

在经过几轮迭代,很多信息都已经消亡,最后只留下一些“斑点”在图像上。

解决问题

重复性

制作hash的时候可以只让生命游戏迭代几轮,而不是一直迭代下去。

信息损失

更改生命游戏的生存规则。

信息增加

通过矩阵异或,将老信息与新信息融合。为什么要用异或呢?因为真值表,真值表andor的信息留存量低于0.5;而xorxnor保留信息恰好是0.5,所以可以选用xor或者xnor

开始制作

重新定义规则

发现信息损失过快之后,我就将生存规则定为了:

  1. 周围有0,1,7,8个细胞的时候,当前细胞为生,则该细胞死亡;如果为死,则保持不变。
  2. 当细胞的周围有2或6个细胞的时候,则这个细胞保留本身的状态,原来为死,现在依旧为死;原来为生,现在依旧为生。
  3. 当一个细胞周围有3,4,5个细胞的时候,原来的为死的细胞,现在为生;原来为生的细胞,现在保持不变。

这样的规则是对称的,一个细胞一周总共有8个细胞。

重新定义迭代轮数(参数名称:all)

迭代all轮的lifegame,得到输出。

重新定义图的大小(参数名称:m,n)

我将图定义为正方形,边长为4,8,16,32个细胞。(相当于4个参数)
实际上是可以定义为m行n列的。

更改每大轮迭代方式

将旧图迭代all轮之后得到新图,新图与旧图进行异或,得到输出。

整体流程设计

引入固定信息

这里参考了MD5码的设计,引入一些固定的信息,引入了A-Z的二进制编码,加在原始数据的前面和后面。

1填补数据

在数据后面填充0,使数据成为图大小的整数倍,也就是m*n的整数倍。

2新入数据

先将output定为一幅图的全0矩阵,将第一幅图与output异或得到的结果输入(新规则的)生命游戏,得到输出output。

2.1新规则的生命游戏

首先按照input与新规则得到output,之后input和output异或得到最终的output并输出。

3迭代

反复使用第2步的output作为输入迭代all轮得到新的output。

4新数据输入

将下一张新图与现有的output进行第2步。

*注意 现在的output不是全0了。

然后执行是步骤3,直到所有的数据图全部处理完毕。

代码

MATLAB代码

lifehash

文件名:lifehash.m

% hash函数
% input:输入的数据
% m:m行
% n:n列
% all:每一张图上做多少次lifegame

function output=lifehash(input,m,n,all)
len=m*n;
% A-Z的二进制编码
x=[1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1;
    1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1;
    0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1;
    0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,1,1,1;
    0,0,0,1,1,1,1,0,0,0,0,1,1,1,1,0,0,0,0,1,1,1,1,0,0,0;
    0,1,1,0,0,1,1,0,0,1,1,0,0,1,1,0,0,1,1,0,0,1,1,0,0,1;
    1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0]';

% 将特定数据插入输入数据的前面和后面
data=[reshape(x,1,[]),reshape(input,1,[]),reshape(x,1,[])];

% reshape把数据补0变为整数张图,每幅图为n列
data=reshape([data,zeros(1,len-mod(length(data(:)),len))],[],n);

% 看data有多少行
L=length(data(:));

% 总共有N幅图
N=L/len;

output=zeros(m,n);
for i=1:N
    % 将数据与原图异或,之后放入lifegame函数
    output=lifegame(xor(output,data(m*(i-1)+1:m*i,:)));
    % 将一幅图循环all轮
    for j=1:all
        output=lifegame(output);
    end
end

lifegame

文件名:lifegame.m

% 对一幅图做一次生命游戏的演化
% input:数据

function output=lifegame(input)
[m,n]=size(input);
output=zeros(m,n);
% 规则:
% 细胞周围为
% 0,1,7,8->死亡
% 2,6->保留
% 3,4,5->繁殖
maintainDown=2;
birthDown=3;
birthUp=5;
maintainUp=6;
for i=1:m
    % 计算一个细胞周围的细胞个数
    if 1==i
        m1=m;
        m2=2;
    elseif m==i
        m1=m-1;
        m2=1;
    else
        m1=i-1;
        m2=i+1;
    end
    for j=1:n
        if 1==j
            n1=n;
            n2=2;
        elseif n==j
            n1=n-1;
            n2=1;
        else
            n1=j-1;
            n2=j+1;
        end
        arround=input(m1,n1)+input(m1,j)+input(m1,n2)+input(i,n1)+input(i,n2)+input(m2,n1)+input(m2,j)+input(m2,n2);

        % 判断这个细胞在新图的状态
        if arround>=birthDown && arround<=birthUp
            output(i,j)=1;
        elseif arround==maintainDown && arround==maintainUp
            output(i,j)=input(i,j);
        else
            output(i,j)=0;
        end
    end
    % 计算完成后,将新的图与旧的图进行异或
    output=xor(output,input);
end

测试

main

文件名:main.m

clear;
all=0;%记录hash相等次数
N=10000;%跑N轮
n=8;%一幅图为8*8
n2=n*n;%图的大小
allfor=4;%lifehash迭代allfor轮
hashShannon=zeros(1,N);%记录Shannon混乱值
h = waitbar(0,'0%','name','hash process');%进度条
for i=1:N
    inp=randi([0,1],100);%第一个输入
    x=lifehash(inp,n,n,allfor);%计算lifehash
    
    %确定一个随机点并更改
    xpos=randi(100);
    ypos=randi(100);
    inp(xpos,ypos)=~inp(xpos,ypos);
    
    y=lifehash(inp,n,n,allfor);%再次计算hash
    z=sum(sum(x==y));%看两次的结果差异
    hashShannon(i)=(n2-z)/n2;%计算Shannon混乱值
    %相同则累加
    if z==n2
        all=all+1;
    end
    
    waitbar(i/N,h,[num2str(i/N*100),'%']);%画进度条
end
close(h);%关闭进度条
histogram(hashShannon,0:0.01:1);%画统计直方图
all
all/N*100

说明

为了隐藏明文信息的冗余度,Shannon提出了混乱与扩散的概念,即加密体制要求充分均匀的利用密文空间。要尽量做到明文对应的Hash值不相关,而对于信息的二进制表示,每比特只能为0或1两种可能,因此理想Hash的扩散效应是初值细微变化导致Hash值50%的变换。

计算两个100*100的随机数据,之后改一个随机点,再算一遍,求得Shannon的混乱值,之后画出统计直方图。

结果

通过修改参数看结果。我测试用的是正方形图,修改x=lifehash(inp,n,n,allfor);%计算lifehash的两个n即可测试长方形图。

n=8, allfor=4

8*8=64位hash
n=8

n=16, allfor=4

16*16=256位hash
n=16

n=8, allfor=1

lifegame迭代1轮。
all=1

n=8, allfor=8

lifegame迭代8轮。
all=8

n=16, allfor=8

图为16*16=256hash,lifegame迭代8轮。
n=16, all=8

问题

  1. 有时混乱值会出现小于0.3,如何去掉混乱小于0.3的部分?
  2. 无论如何改变参数,都会出现相等的hash,并且数量占比保持恒定的2.1%左右。
  3. 如何将峰值趋向0.5?
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

FishPotatoChen

谢谢您的支持,我会更努力的~

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值