2017-06-21 66 views
1

为了调试,我希望比较几个对象,并为它们创建一些唯一的ID,并根据其内容和结构,ID应该相等。有没有这样做的现有功能?Matlab为变量创建MD5校验和

例如,如果一个对象是一个结构:

S: 
S.a1 = 1 
S.a2 = 2 
S.b1 = 3 
    S.b11 = 4 
    S.b12 = 5 
S.c1 = 6 

我的当前选择其复制到磁盘并计算MD5 64位校验和。

function d=checksum(x) 
%% Create unique identifier for variable 
save('~$hashid.ini',x); 
d=md5('~$hashid.ini'); 
delete('~$hashid.ini'); 

这是完全没有办法,想要做几个对象和调试。但由于该文件的更新日期而不工作。...

回答

1

提到了一种解决方案hereDataHash功能是解决方案:

function H = DataHash(Data) 
Engine = java.security.MessageDigest.getInstance('MD5'); 
H = CoreHash(Data, Engine); 
H = sprintf('%.2x', H); % To hex string 


function H = CoreHash(Data, Engine) 
% Consider the type of empty arrays: 
S = [class(Data), sprintf('%d ', size(Data))]; 
Engine.update(typecast(uint16(S(:)), 'uint8')); 
H = double(typecast(Engine.digest, 'uint8')); 
if isa(Data, 'struct') 
    n = numel(Data); 
    if n == 1 % Scalar struct: 
     F = sort(fieldnames(Data)); % ignore order of fields 
     for iField = 1:length(F) 
     H = bitxor(H, CoreHash(Data.(F{iField}), Engine)); 
     end 
    else % Struct array: 
     for iS = 1:n 
     H = bitxor(H, CoreHash(Data(iS), Engine)); 
     end 
    end 
elseif isempty(Data) 
    % No further actions needed 
elseif isnumeric(Data) 
    Engine.update(typecast(Data(:), 'uint8')); 
    H = bitxor(H, double(typecast(Engine.digest, 'uint8'))); 
elseif ischar(Data) % Silly TYPECAST cannot handle CHAR 
    Engine.update(typecast(uint16(Data(:)), 'uint8')); 
    H = bitxor(H, double(typecast(Engine.digest, 'uint8'))); 
elseif iscell(Data) 
    for iS = 1:numel(Data) 
     H = bitxor(H, CoreHash(Data{iS}, Engine)); 
    end 
elseif islogical(Data) 
    Engine.update(typecast(uint8(Data(:)), 'uint8')); 
    H = bitxor(H, double(typecast(Engine.digest, 'uint8'))); 
elseif isa(Data, 'function_handle') 
    H = bitxor(H, CoreHash(functions(Data), Engine)); 
else 
    warning(['Type of variable not considered: ', class(Data)]); 
end 

此外,你可以找到的代码here的完整版本。

+0

这正是我想要的解决方案。我已经实现了它。 – hyprfrcb

1

比@OmG的回答更普遍的解决方案,它依赖于无证一点点功能:

function str = hash(in) 

% Get a bytestream from the input. Note that this calls saveobj. 
inbs = getByteStreamFromArray(in); 

% Create hash using Java Security Message Digest. 
md = java.security.MessageDigest.getInstance('SHA1'); 
md.update(inbs); 

% Convert to uint8. 
d = typecast(md.digest, 'uint8'); 

% Convert to a hex string. 
str = dec2hex(d)'; 
str = lower(str(:)'); 

的无证功能getByteStreamFromArray的回报,如果你是会被写入到磁盘字节流调用变量上的save -v7命令。它适用于任何小于2GB大小的变量,不仅包括@OmG的CoreHash涵盖的内置类型(数字,逻辑,结构,单元格等),还包含内置和用户定义的类以及。

请注意,getByteStreamFromArray调用saveobj,所以它将忽略Transient属性 - 这对于散列和保存几乎肯定是一件好事。

PS在任一解决方案中,SHA1可能比MD5更好。