Matlab为变量创建MD5校验和

Matlab为变量创建MD5校验和,matlab,md5,checksum,Matlab,Md5,Checksum,对于调试,我希望比较几个对象,并为每个对象创建一些唯一的ID,根据其内容和结构,ID应该相等。是否存在执行此操作的现有功能 例如,如果对象是一个结构: S: S.a1 = 1 S.a2 = 2 S.b1 = 3 S.b11 = 4 S.b12 = 5 S.c1 = 6 我当前的选择是将其复制到磁盘并计算MD5 64位校验和,这不起作用,因为此哈希取决于文件的修改日期。提到了一种解决方案DataHash函数是解决方案: function H = DataHash(Data)

对于调试,我希望比较几个对象,并为每个对象创建一些唯一的ID,根据其内容和结构,ID应该相等。是否存在执行此操作的现有功能

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

S:
 S.a1 = 1
 S.a2 = 2
 S.b1 = 3
   S.b11 = 4
   S.b12 = 5
 S.c1 = 6
我当前的选择是将其复制到磁盘并计算MD5 64位校验和,这不起作用,因为此哈希取决于文件的修改日期。

提到了一种解决方案
DataHash
函数是解决方案:

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

此外,您还可以找到代码的完整版本。

这是一个比@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
所涵盖的内置类型(数字、逻辑、结构、单元格等),还包括内置和用户定义的类

请注意,
getByTestStreamFromArray
调用
saveobj
,因此它将忽略
瞬态
属性-这几乎肯定是哈希和保存的好方法


PS在这两种解决方案中,SHA1可能比MD5更好。

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