2017-06-21 15 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

here 1つのソリューションが記載されています。

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の完全なバージョンを見つけることができます:DataHash機能は、そのソリューションです。

+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コマンドを呼び出します。 @OmGのCoreHashで扱われる組み込み型(数値、論理、構造体、セルなど)だけでなく、ビルトインおよびユーザー定義のクラスも含め、サイズが2GB未満の任意の変数に対して機能します同じように。

getByteStreamFromArraysaveobjを呼び出すため、Transientのプロパティは無視されます。これは、ほとんどの場合、ハッシングと保存のためには良いことです。

PSどちらのソリューションでも、SHA1はおそらくMD5より優れています。

関連する問題