/ concept-collection / seqlab
Sign in
concept-collection / seqlab
seqlab / src / engine / pulseq / +mr / verifyFileSignature.m
93 lines · 3.1 KBCodeBlameHistory
78d04f1seqlab: write and view pulseq MRI sequences in the browserJeremy Magland 1function [res, storedSignature, computedSignature] = verifyFileSignature(pulseqFile)
2% verifyFileSignature - verify the signature of the provided Pulseq file.
3% both text and binary Pulseq files are supported.
4%
5
6 fid = fopen(pulseqFile, 'r');
7 assert(fid>=0, 'Failed to open file: %s', pulseqFile);
8 cleanupObj = onCleanup(@() fclose(fid));
9
10 % check whether this is a binary file
11 binaryCodes = mr.Sequence.getBinaryCodes();
12 magicNum = fread(fid,1,'uint64=>uint64');
13 isBinary = magicNum==binaryCodes.fileHeader;
15 if isBinary
16 [ok, sigType, storedSignature, signedLen] = readBinaryFileSignature(fid,binaryCodes);
17 else
18 [ok, sigType, storedSignature, signedLen] = readTextFileSignature(fid);
19 % need to close and reopen the file to reset the 'text' state of the file handle (stupid Matlab)
20 fclose(fid);
21 fid = fopen(pulseqFile, 'r');
22 end
24 if ~ok
25 error('failed to read the signature');
26 end
28 computedSignature = computeMd5OfPrefix(fid, signedLen);
29 res=strcmp(computedSignature,storedSignature);
30end
32function [ok, sigType, sigHex, signedLen] = readBinaryFileSignature(fid,binaryCodes)
33 fseek(fid, -8, 'eof');
34 signedLen = double(fread(fid, 1, 'int64'));
36 fseek(fid, signedLen, 'bof');
37 sectionCode = int64(fread(fid, 1, 'int64'));
38 assert(sectionCode==binaryCodes.section.signature);
40 typeLen = double(fread(fid, 1, 'int32'));
41 sigType = char(fread(fid, typeLen, 'char')');
43 hashLen = double(fread(fid, 1, 'int32'));
44 hashRaw = uint8(fread(fid, hashLen, 'uint8'));
45 if isempty(hashRaw)
46 sigHex = '';
47 else
48 sigHex = lower(reshape(dec2hex(hashRaw, 2)', 1, []));
49 end
50 ok = true; % more checks?
51end
53function [ok, sigType, sigHex, signedLen] = readTextFileSignature(fid)
54 sigType='';
55 sigHex='';
56 signedLen=-1;
57 fseek(fid, 0, 'bof');
58 fLeadingNewLinePos=-1;
59 while ~feof(fid)
60 fpos=ftell(fid);
61 line = fgetl(fid);
62 if signedLen<=0
63 % still looking for the SIGNATURE marker
64 if length(line)>=11 && strcmp('[SIGNATURE]',line(1:11))
65 assert(fLeadingNewLinePos>0);
66 signedLen = fLeadingNewLinePos;
67 end
68 if length(line)==0
69 fLeadingNewLinePos=fpos;
70 else
71 fLeadingNewLinePos=-1;
72 end
73 else
74 % reading the signature
75 if length(line)<=5 || line(1)=='#'
76 continue;
77 end
78 if strcmp('Type ',line(1:5))
79 sigType=mr.aux.strstrip(line(6:end));
80 end
81 if strcmp('Hash ',line(1:5))
82 sigHex=lower(mr.aux.strstrip(line(6:end)));
83 end
84 end
85 end
86 ok = ~isempty(sigType) && ~isempty(sigHex) && signedLen>0;
87end
89function md5Hex = computeMd5OfPrefix(fid, signedLen)
90 fseek(fid, 0, 'bof');
91 payload = fread(fid, signedLen);%, 'uint8=>uint8');
92 md5Hex = mr.aux.md5(payload);
93end
moveopenescclose