以下是用於在ASCII值文件上生成MD5摘要的M文件。我有一串HEX值並將其轉換爲ASCII,然後將這些值寫入傳遞給md5函數的文件。我正在使用兩個不同的在線MD5計算器來驗證腳本的解決方案。 Here is one of them.爲什麼這個MD5 Matlab的實現在某些消息大小的時候發生崩潰?
我從HEX字符串轉換爲ACSII的方法是將兩個十六進制值配對,然後將這些對轉換爲ASCII字符,然後將其寫入文件。我知道這樣做是正確的,因爲我可以將HEX字符串傳遞給上面提到的在線計算器,或者上傳它們等效的ASCII表示,並且即使MATLAB腳本給出了錯誤的摘要,它們也會產生相同的(有效)結果。
由於某些原因,摘要是否正確計算取決於從文件中讀取的ASCII值的數量。我試圖瞭解這種行爲是否存在任何模式,但我找不到任何模式。它爲200,300到322,500,996,998,1008,1010,1050,1070,1076 HEX字符的消息生成一個有效的摘要,這些HEX字符首先被轉換爲ASCII文件。但不適用於1000,1002,1004,1006,1078,1100 HEX字符。總之,我沒有看到這種瘋狂的方法...任何幫助將不勝感激。
% md5 Compute MD5 hash function for files
%
% d = md5(FileName)
%
% md5() computes the MD5 hash function of
% the file specified in the string FileName
% and returns it as a 64-character array d.
% The MD5 message-digest algorithm is specified
% in RFC 1321.
% The code below is for instructional and illustrational
% purposes only. It is very clear, but very slow.
% (C) Stefan Stoll, ETH Zurich, 2006
function Digest = md5(FileName)
% Guard against old Matlab versions
MatlabVersion = version;
if MatlabVersion(1)<'7'
error('md5() requires Matlab 7.0 or later!');
end
% Run autotest if no parameters are given
if (nargin==0)
md5autotest;
return;
end
% Read in entire file into uint32 vector
[Message,nBits] = readmessagefromfile(FileName);
%--------------------------------------------------
% Append a bit-1 to the last bit read from file
BytesInLastInt = mod(nBits,32)/8;
if BytesInLastInt
Message(end) = bitset(Message(end),BytesInLastInt*8+8);
else
Message = [Message; uint32(128)];
end
% Append zeros
nZeros = 16 - mod(numel(Message)+2,16);
Message = [Message; zeros(nZeros,1,'uint32')];
% Append bit length of original message as uint64, lower significant uint32 first
Lower32 = uint32(nBits);
Upper32 = uint32(bitshift(uint64(nBits),-32));
Message = [Message; Lower32; Upper32];
%--------------------------------------------------
% 64-element transformation array
T = uint32(fix(4294967296*abs(sin(1:64))));
% 64-element array of number of bits for circular left shift
S = repmat([7 12 17 22; 5 9 14 20; 4 11 16 23; 6 10 15 21].',4,1);
S = S(:).';
% 64-element array of indices into X
idxX = [0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 ...
1 6 11 0 5 10 15 4 9 14 3 8 13 2 7 12 ...
5 8 11 14 1 4 7 10 13 0 3 6 9 12 15 2 ...
0 7 14 5 12 3 10 1 8 15 6 13 4 11 2 9] + 1;
% Initial state of buffer (consisting of A, B, C and D)
A = uint32(hex2dec('67452301'));
B = uint32(hex2dec('efcdab89'));
C = uint32(hex2dec('98badcfe'));
D = uint32(hex2dec('10325476'));
%--------------------------------------------------
Message = reshape(Message,16,[]);
% Loop over message blocks each 16 uint32 long
for iBlock = 1:size(Message,2)
% Extract next block
X = Message(:,iBlock);
% Store current buffer state
AA = A;
BB = B;
CC = C;
DD = D;
% Transform buffer using message block X and the
% parameters from S, T and idxX
k = 0;
for iRound = 1:4
for q = 1:4
A = Fun(iRound,A,B,C,D,X(idxX(k+1)),S(k+1),T(k+1));
D = Fun(iRound,D,A,B,C,X(idxX(k+2)),S(k+2),T(k+2));
C = Fun(iRound,C,D,A,B,X(idxX(k+3)),S(k+3),T(k+3));
B = Fun(iRound,B,C,D,A,X(idxX(k+4)),S(k+4),T(k+4));
k = k + 4;
end
end
% Add old buffer state
A = bitadd32(A,AA);
B = bitadd32(B,BB);
C = bitadd32(C,CC);
D = bitadd32(D,DD);
end
%--------------------------------------------------
% Combine uint32 from buffer to form message digest
Str = lower(dec2hex([A;B;C;D]));
Str = Str(:,[7 8 5 6 3 4 1 2]).';
Digest = Str(:).';
%==================================================
function y = Fun(iRound,a,b,c,d,x,s,t)
switch iRound
case 1
q = bitor(bitand(b,c),bitand(bitcmp(b),d));
case 2
q = bitor(bitand(b,d),bitand(c,bitcmp(d)));
case 3
q = bitxor(bitxor(b,c),d);
case 4
q = bitxor(c,bitor(b,bitcmp(d)));
end
y = bitadd32(b,rotateleft32(bitadd32(a,q,x,t),s));
%--------------------------------------------
function y = rotateleft32(x,s)
y = bitor(bitshift(x,s),bitshift(x,s-32));
%--------------------------------------------
function sum = bitadd32(varargin)
sum = varargin{1};
for k = 2:nargin
add = varargin{k};
carry = bitand(sum,add);
sum = bitxor(sum,add);
for q = 1:32
shift = bitshift(carry,1);
carry = bitand(shift,sum);
sum = bitxor(shift,sum);
end
end
function [Message,nBits] = readmessagefromfile(FileName)
[hFile,ErrMsg] = fopen(FileName,'r');
error(ErrMsg);
%Message = fread(hFile,inf,'bit32=>uint32');
Message = fread(hFile,inf,'ubit32=>uint32');
%Message = fread(hFile);
fclose(hFile);
d = dir(FileName);
nBits = d.bytes*8;
%============================================
function md5autotest
disp('Running md5 autotest...');
Messages{1} = '';
Messages{2} = 'a';
Messages{3} = 'abc';
Messages{4} = 'message digest';
Messages{5} = 'abcdefghijklmnopqrstuvwxyz';
Messages{6} = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz';
Messages{7} = char(128:255);
CorrectDigests{1} = 'd41d8cd98f00b204e9800998ecf8427e';
CorrectDigests{2} = '0cc175b9c0f1b6a831c399e269772661';
CorrectDigests{3} = '900150983cd24fb0d6963f7d28e17f72';
CorrectDigests{4} = 'f96b697d7cb7938d525a2f31aaf161d0';
CorrectDigests{5} = 'c3fcd3d76192e4007dfb496cca67e13b';
CorrectDigests{6} = 'd174ab98d277d9f5a5611c2c9f419d9f';
CorrectDigests{7} = '16f404156c0500ac48efa2d3abc5fbcf';
TmpFile = tempname;
for k=1:numel(Messages)
[h,ErrMsg] = fopen(TmpFile,'w');
error(ErrMsg);
fwrite(h,Messages{k},'char');
fclose(h);
Digest = md5(TmpFile);
fprintf('%d: %s\n',k,Digest);
if ~strcmp(Digest,CorrectDigests{k})
error('md5 autotest failed on the following string: %s',Messages{k});
end
end
delete(TmpFile);
disp('md5 autotest passed!');
請包含一個示例文件,它會導致問題。 – Daniel
在我的機器上,自檢失敗,因爲參考值錯誤。根據unix md5sum,它應該是'CorrectDigests {7} ='946c295284edb33cb8a62bed8120c9f1'' – Daniel
明天我將爲成功和不成功的摘要提供一個示例文件。奇怪的是,自我測試不會在我一直使用的計算機上失敗。但是你發佈的摘要是正確的,並且通過在線計算器進行確認。然而,腳本的自我測試給出了不正確的答案,如果我使用data = char(128:255) - > fwrite(fopen('text.txt','wt'),data) - > md5手動寫入文件('test.txt')我得到Digest = 16f404156c0500ac48efa2d3abc5fbcf – Falimond