2017-06-21 270 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更好。