Added md5 hashing of binary files

This commit is contained in:
Graham Nelson 2022-03-05 21:36:26 +00:00
parent df15511d7e
commit a8e6c508ac
8 changed files with 329 additions and 14 deletions

View file

@ -1,6 +1,6 @@
# Inweb 7
v7-alpha.1+1A78 'Escape to Danger' (13 February 2022)
v7-alpha.1+1A79 'Escape to Danger' (5 March 2022)
## About Inweb

View file

@ -1,3 +1,3 @@
Prerelease: alpha.1
Build Date: 13 February 2022
Build Number: 1A78
Build Date: 5 March 2022
Build Number: 1A79

View file

@ -115,7 +115,7 @@ the temporary stream, not some other string which might need fresh allocation.
<span class="plain-syntax"> </span><span class="identifier-syntax">DISCARD_TEXT</span><span class="plain-syntax">(</span><span class="identifier-syntax">ERM</span><span class="plain-syntax">)</span>
<span class="plain-syntax">}</span>
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">Errors::fatal_with_file</span><button class="popup" onclick="togglePopup('usagePopup6')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup6">Usage of <span class="code-font"><span class="function-syntax">Errors::fatal_with_file</span></span>:<br/>Text Files - <a href="4-tf.html#SP5_1">&#167;5.1</a>, <a href="4-tf.html#SP5_2">&#167;5.2</a>, <a href="4-tf.html#SP5_3_2">&#167;5.3.2</a><br/>Epub Ebooks - <a href="5-ee.html#SP6_1">&#167;6.1</a>, <a href="5-ee.html#SP6_2">&#167;6.2</a>, <a href="5-ee.html#SP6_3">&#167;6.3</a>, <a href="5-ee.html#SP7_2">&#167;7.2</a>, <a href="5-ee.html#SP7_3">&#167;7.3</a><br/>Binary Files - <a href="6-bf.html#SP7">&#167;7</a>, <a href="6-bf.html#SP8">&#167;8</a>, <a href="6-bf.html#SP9">&#167;9</a><br/>Build Files - <a href="8-bf.html#SP4">&#167;4</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">char</span><span class="plain-syntax"> *</span><span class="identifier-syntax">message</span><span class="plain-syntax">, </span><span class="reserved-syntax">filename</span><span class="plain-syntax"> *</span><span class="identifier-syntax">F</span><span class="plain-syntax">) {</span>
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">Errors::fatal_with_file</span><button class="popup" onclick="togglePopup('usagePopup6')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup6">Usage of <span class="code-font"><span class="function-syntax">Errors::fatal_with_file</span></span>:<br/>Text Files - <a href="4-tf.html#SP5_1">&#167;5.1</a>, <a href="4-tf.html#SP5_2">&#167;5.2</a>, <a href="4-tf.html#SP5_3_2">&#167;5.3.2</a><br/>Epub Ebooks - <a href="5-ee.html#SP6_1">&#167;6.1</a>, <a href="5-ee.html#SP6_2">&#167;6.2</a>, <a href="5-ee.html#SP6_3">&#167;6.3</a>, <a href="5-ee.html#SP7_2">&#167;7.2</a>, <a href="5-ee.html#SP7_3">&#167;7.3</a><br/>Binary Files - <a href="6-bf.html#SP7">&#167;7</a>, <a href="6-bf.html#SP8">&#167;8</a>, <a href="6-bf.html#SP9">&#167;9</a>, <a href="6-bf.html#SP10">&#167;10</a><br/>Build Files - <a href="8-bf.html#SP4">&#167;4</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">char</span><span class="plain-syntax"> *</span><span class="identifier-syntax">message</span><span class="plain-syntax">, </span><span class="reserved-syntax">filename</span><span class="plain-syntax"> *</span><span class="identifier-syntax">F</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">TEMPORARY_TEXT</span><span class="plain-syntax">(</span><span class="identifier-syntax">ERM</span><span class="plain-syntax">)</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">WRITE_TO</span><span class="plain-syntax">(</span><span class="identifier-syntax">ERM</span><span class="plain-syntax">, </span><span class="string-syntax">"%s: fatal error: %s: %f\n"</span><span class="plain-syntax">, </span><span class="identifier-syntax">PROGRAM_NAME</span><span class="plain-syntax">, </span><span class="identifier-syntax">message</span><span class="plain-syntax">, </span><span class="identifier-syntax">F</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><a href="3-em.html#SP1" class="function-link"><span class="function-syntax">Errors::issue</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">ERM</span><span class="plain-syntax">, </span><span class="constant-syntax">TRUE</span><span class="plain-syntax">);</span>

View file

@ -20,6 +20,20 @@ function togglePopup(material_id) {
</script>
<link href="../docs-assets/Popups.css" rel="stylesheet" rev="stylesheet" type="text/css">
<script>
MathJax = {
tex: {
inlineMath: '$', '$'], ['\\(', '\\)'
},
svg: {
fontCache: 'global'
}
};
</script>
<script type="text/javascript" id="MathJax-script" async
src="https://cdn.jsdelivr.net/npm/mathjax@3/es5/tex-svg.js">
</script>
<link href="../docs-assets/Colours.css" rel="stylesheet" rev="stylesheet" type="text/css">
</head>
@ -50,14 +64,14 @@ function togglePopup(material_id) {
<ul class="crumbs"><li><a href="../index.html">Home</a></li><li><a href="index.html">foundation</a></li><li><a href="index.html#6">Chapter 6: Media</a></li><li><b>Binary Files</b></li></ul></div>
<p class="purpose">Routines for reading raw data from binary files.</p>
<ul class="toc"><li><a href="6-bf.html#SP1">&#167;1. Reading binary data</a></li><li><a href="6-bf.html#SP7">&#167;7. Size</a></li><li><a href="6-bf.html#SP8">&#167;8. Opening</a></li><li><a href="6-bf.html#SP9">&#167;9. Copying</a></li></ul><hr class="tocbar">
<ul class="toc"><li><a href="6-bf.html#SP1">&#167;1. Reading binary data</a></li><li><a href="6-bf.html#SP7">&#167;7. Size</a></li><li><a href="6-bf.html#SP8">&#167;8. Opening</a></li><li><a href="6-bf.html#SP9">&#167;9. Copying</a></li><li><a href="6-bf.html#SP10">&#167;10. MD5 hash computation</a></li></ul><hr class="tocbar">
<p class="commentary firstcommentary"><a id="SP1" class="paragraph-anchor"></a><b>&#167;1. Reading binary data. </b>To begin with, integers of 8, 16, 32 and 64 bit widths respectively,
arranged with most significant byte (MSB) first.
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="function-syntax">BinaryFiles::read_int8</span><button class="popup" onclick="togglePopup('usagePopup1')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup1">Usage of <span class="code-font"><span class="function-syntax">BinaryFiles::read_int8</span></span>:<br/>Sound Durations - <a href="6-sd.html#SP2">&#167;2</a>, <a href="6-sd.html#SP3">&#167;3</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">FILE</span><span class="plain-syntax"> *</span><span class="identifier-syntax">binary_file</span><span class="plain-syntax">, </span><span class="reserved-syntax">unsigned</span><span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> *</span><span class="identifier-syntax">result</span><span class="plain-syntax">) {</span>
<span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="function-syntax">BinaryFiles::read_int8</span><button class="popup" onclick="togglePopup('usagePopup1')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup1">Usage of <span class="code-font"><span class="function-syntax">BinaryFiles::read_int8</span></span>:<br/><a href="6-bf.html#SP10">&#167;10</a><br/>Sound Durations - <a href="6-sd.html#SP2">&#167;2</a>, <a href="6-sd.html#SP3">&#167;3</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">FILE</span><span class="plain-syntax"> *</span><span class="identifier-syntax">binary_file</span><span class="plain-syntax">, </span><span class="reserved-syntax">unsigned</span><span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> *</span><span class="identifier-syntax">result</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">c1</span><span class="plain-syntax"> = </span><span class="identifier-syntax">getc</span><span class="plain-syntax">(</span><span class="identifier-syntax">binary_file</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">c1</span><span class="plain-syntax"> == </span><span class="identifier-syntax">EOF</span><span class="plain-syntax">) </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="constant-syntax">FALSE</span><span class="plain-syntax">;</span>
@ -237,13 +251,13 @@ be at least <span class="extract"><span class="extract-syntax">length</span></sp
<p class="commentary firstcommentary"><a id="SP8" class="paragraph-anchor"></a><b>&#167;8. Opening. </b></p>
<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">FILE</span><span class="plain-syntax"> *</span><span class="function-syntax">BinaryFiles::open_for_reading</span><span class="plain-syntax">(</span><span class="reserved-syntax">filename</span><span class="plain-syntax"> *</span><span class="identifier-syntax">F</span><span class="plain-syntax">) {</span>
<span class="reserved-syntax">FILE</span><span class="plain-syntax"> *</span><span class="function-syntax">BinaryFiles::open_for_reading</span><button class="popup" onclick="togglePopup('usagePopup10')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup10">Usage of <span class="code-font"><span class="function-syntax">BinaryFiles::open_for_reading</span></span>:<br/><a href="6-bf.html#SP10">&#167;10</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">filename</span><span class="plain-syntax"> *</span><span class="identifier-syntax">F</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">FILE</span><span class="plain-syntax"> *</span><span class="identifier-syntax">handle</span><span class="plain-syntax"> = </span><a href="3-fln.html#SP10" class="function-link"><span class="function-syntax">Filenames::fopen</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">F</span><span class="plain-syntax">, </span><span class="string-syntax">"rb"</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">handle</span><span class="plain-syntax"> == </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">) </span><a href="3-em.html#SP2" class="function-link"><span class="function-syntax">Errors::fatal_with_file</span></a><span class="plain-syntax">(</span><span class="string-syntax">"unable to read file"</span><span class="plain-syntax">, </span><span class="identifier-syntax">F</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">handle</span><span class="plain-syntax">;</span>
<span class="plain-syntax">}</span>
<span class="reserved-syntax">FILE</span><span class="plain-syntax"> *</span><span class="function-syntax">BinaryFiles::try_to_open_for_reading</span><button class="popup" onclick="togglePopup('usagePopup10')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup10">Usage of <span class="code-font"><span class="function-syntax">BinaryFiles::try_to_open_for_reading</span></span>:<br/><a href="6-bf.html#SP7">&#167;7</a>, <a href="6-bf.html#SP9">&#167;9</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">filename</span><span class="plain-syntax"> *</span><span class="identifier-syntax">F</span><span class="plain-syntax">) {</span>
<span class="reserved-syntax">FILE</span><span class="plain-syntax"> *</span><span class="function-syntax">BinaryFiles::try_to_open_for_reading</span><button class="popup" onclick="togglePopup('usagePopup11')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup11">Usage of <span class="code-font"><span class="function-syntax">BinaryFiles::try_to_open_for_reading</span></span>:<br/><a href="6-bf.html#SP7">&#167;7</a>, <a href="6-bf.html#SP9">&#167;9</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">filename</span><span class="plain-syntax"> *</span><span class="identifier-syntax">F</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><a href="3-fln.html#SP10" class="function-link"><span class="function-syntax">Filenames::fopen</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">F</span><span class="plain-syntax">, </span><span class="string-syntax">"rb"</span><span class="plain-syntax">);</span>
<span class="plain-syntax">}</span>
@ -253,11 +267,11 @@ be at least <span class="extract"><span class="extract-syntax">length</span></sp
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">handle</span><span class="plain-syntax">;</span>
<span class="plain-syntax">}</span>
<span class="reserved-syntax">FILE</span><span class="plain-syntax"> *</span><span class="function-syntax">BinaryFiles::try_to_open_for_writing</span><button class="popup" onclick="togglePopup('usagePopup11')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup11">Usage of <span class="code-font"><span class="function-syntax">BinaryFiles::try_to_open_for_writing</span></span>:<br/><a href="6-bf.html#SP9">&#167;9</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">filename</span><span class="plain-syntax"> *</span><span class="identifier-syntax">F</span><span class="plain-syntax">) {</span>
<span class="reserved-syntax">FILE</span><span class="plain-syntax"> *</span><span class="function-syntax">BinaryFiles::try_to_open_for_writing</span><button class="popup" onclick="togglePopup('usagePopup12')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup12">Usage of <span class="code-font"><span class="function-syntax">BinaryFiles::try_to_open_for_writing</span></span>:<br/><a href="6-bf.html#SP9">&#167;9</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">filename</span><span class="plain-syntax"> *</span><span class="identifier-syntax">F</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><a href="3-fln.html#SP10" class="function-link"><span class="function-syntax">Filenames::fopen</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">F</span><span class="plain-syntax">, </span><span class="string-syntax">"wb"</span><span class="plain-syntax">);</span>
<span class="plain-syntax">}</span>
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">BinaryFiles::close</span><button class="popup" onclick="togglePopup('usagePopup12')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup12">Usage of <span class="code-font"><span class="function-syntax">BinaryFiles::close</span></span>:<br/><a href="6-bf.html#SP7">&#167;7</a>, <a href="6-bf.html#SP9">&#167;9</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">FILE</span><span class="plain-syntax"> *</span><span class="identifier-syntax">handle</span><span class="plain-syntax">) {</span>
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">BinaryFiles::close</span><button class="popup" onclick="togglePopup('usagePopup13')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup13">Usage of <span class="code-font"><span class="function-syntax">BinaryFiles::close</span></span>:<br/><a href="6-bf.html#SP7">&#167;7</a>, <a href="6-bf.html#SP9">&#167;9</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">FILE</span><span class="plain-syntax"> *</span><span class="identifier-syntax">handle</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">fclose</span><span class="plain-syntax">(</span><span class="identifier-syntax">handle</span><span class="plain-syntax">);</span>
<span class="plain-syntax">}</span>
</pre>
@ -293,6 +307,159 @@ or to system APIs.
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">size</span><span class="plain-syntax">;</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP10" class="paragraph-anchor"></a><b>&#167;10. MD5 hash computation. </b>Though now seen as insecure from a cryptographic point of view, Message Digest 5,
a form of checksum created by Ronald Rivest in 1992, remains very useful as a
way to compare files quickly, at least when we're sure nobody is being malicious.
</p>
<p class="commentary">There are thousands of amateur implementations, most of them, like this one,
paraphrased from the pseudocode at the Wikipedia page. The <span class="extract"><span class="extract-syntax">mask</span></span> function allows
certain fixed byte positions in the file to be considered as if they were zero bytes,
which is helpful when testing comparing files whose headers change in uninteresting
ways. If <span class="extract"><span class="extract-syntax">mask</span></span> is <span class="extract"><span class="extract-syntax">NULL</span></span>, or always returns <span class="extract"><span class="extract-syntax">FALSE</span></span>, then the hash computed is
exactly the canonical md5.
</p>
<p class="commentary">The code below is about as enigmatic as a page of well-meaning code can be, but
that's down to the algorithm itself. The <span class="extract"><span class="extract-syntax">K</span></span> array hold bits drawn from the sines
of the integers 1 to 64: sines computed in radians, so that in a sense the md5
algorithm relies on the irrationality of \(\pi\) to make these so unpredictable.
At any rate, the magic numbers below are all drawn from RFC 1321.
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">BinaryFiles::md5</span><span class="plain-syntax">(</span><span class="constant-syntax">OUTPUT_STREAM</span><span class="plain-syntax">, </span><span class="reserved-syntax">filename</span><span class="plain-syntax"> *</span><span class="identifier-syntax">F</span><span class="plain-syntax">, </span><span class="reserved-syntax">int</span><span class="plain-syntax"> (*</span><span class="identifier-syntax">mask</span><span class="plain-syntax">)(</span><span class="identifier-syntax">uint64_t</span><span class="plain-syntax">)) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">uint32_t</span><span class="plain-syntax"> </span><span class="identifier-syntax">s</span><span class="plain-syntax">[64] = {</span>
<span class="plain-syntax"> </span><span class="constant-syntax">7</span><span class="plain-syntax">, </span><span class="constant-syntax">12</span><span class="plain-syntax">, </span><span class="constant-syntax">17</span><span class="plain-syntax">, </span><span class="constant-syntax">22</span><span class="plain-syntax">, </span><span class="constant-syntax">7</span><span class="plain-syntax">, </span><span class="constant-syntax">12</span><span class="plain-syntax">, </span><span class="constant-syntax">17</span><span class="plain-syntax">, </span><span class="constant-syntax">22</span><span class="plain-syntax">, </span><span class="constant-syntax">7</span><span class="plain-syntax">, </span><span class="constant-syntax">12</span><span class="plain-syntax">, </span><span class="constant-syntax">17</span><span class="plain-syntax">, </span><span class="constant-syntax">22</span><span class="plain-syntax">, </span><span class="constant-syntax">7</span><span class="plain-syntax">, </span><span class="constant-syntax">12</span><span class="plain-syntax">, </span><span class="constant-syntax">17</span><span class="plain-syntax">, </span><span class="constant-syntax">22</span><span class="plain-syntax">,</span>
<span class="plain-syntax"> </span><span class="constant-syntax">5</span><span class="plain-syntax">, </span><span class="constant-syntax">9</span><span class="plain-syntax">, </span><span class="constant-syntax">14</span><span class="plain-syntax">, </span><span class="constant-syntax">20</span><span class="plain-syntax">, </span><span class="constant-syntax">5</span><span class="plain-syntax">, </span><span class="constant-syntax">9</span><span class="plain-syntax">, </span><span class="constant-syntax">14</span><span class="plain-syntax">, </span><span class="constant-syntax">20</span><span class="plain-syntax">, </span><span class="constant-syntax">5</span><span class="plain-syntax">, </span><span class="constant-syntax">9</span><span class="plain-syntax">, </span><span class="constant-syntax">14</span><span class="plain-syntax">, </span><span class="constant-syntax">20</span><span class="plain-syntax">, </span><span class="constant-syntax">5</span><span class="plain-syntax">, </span><span class="constant-syntax">9</span><span class="plain-syntax">, </span><span class="constant-syntax">14</span><span class="plain-syntax">, </span><span class="constant-syntax">20</span><span class="plain-syntax">,</span>
<span class="plain-syntax"> </span><span class="constant-syntax">4</span><span class="plain-syntax">, </span><span class="constant-syntax">11</span><span class="plain-syntax">, </span><span class="constant-syntax">16</span><span class="plain-syntax">, </span><span class="constant-syntax">23</span><span class="plain-syntax">, </span><span class="constant-syntax">4</span><span class="plain-syntax">, </span><span class="constant-syntax">11</span><span class="plain-syntax">, </span><span class="constant-syntax">16</span><span class="plain-syntax">, </span><span class="constant-syntax">23</span><span class="plain-syntax">, </span><span class="constant-syntax">4</span><span class="plain-syntax">, </span><span class="constant-syntax">11</span><span class="plain-syntax">, </span><span class="constant-syntax">16</span><span class="plain-syntax">, </span><span class="constant-syntax">23</span><span class="plain-syntax">, </span><span class="constant-syntax">4</span><span class="plain-syntax">, </span><span class="constant-syntax">11</span><span class="plain-syntax">, </span><span class="constant-syntax">16</span><span class="plain-syntax">, </span><span class="constant-syntax">23</span><span class="plain-syntax">,</span>
<span class="plain-syntax"> </span><span class="constant-syntax">6</span><span class="plain-syntax">, </span><span class="constant-syntax">10</span><span class="plain-syntax">, </span><span class="constant-syntax">15</span><span class="plain-syntax">, </span><span class="constant-syntax">21</span><span class="plain-syntax">, </span><span class="constant-syntax">6</span><span class="plain-syntax">, </span><span class="constant-syntax">10</span><span class="plain-syntax">, </span><span class="constant-syntax">15</span><span class="plain-syntax">, </span><span class="constant-syntax">21</span><span class="plain-syntax">, </span><span class="constant-syntax">6</span><span class="plain-syntax">, </span><span class="constant-syntax">10</span><span class="plain-syntax">, </span><span class="constant-syntax">15</span><span class="plain-syntax">, </span><span class="constant-syntax">21</span><span class="plain-syntax">, </span><span class="constant-syntax">6</span><span class="plain-syntax">, </span><span class="constant-syntax">10</span><span class="plain-syntax">, </span><span class="constant-syntax">15</span><span class="plain-syntax">, </span><span class="constant-syntax">21</span><span class="plain-syntax"> };</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">uint32_t</span><span class="plain-syntax"> </span><span class="identifier-syntax">K</span><span class="plain-syntax">[64] = {</span>
<span class="plain-syntax"> </span><span class="constant-syntax">0xd76aa478</span><span class="plain-syntax">, </span><span class="constant-syntax">0xe8c7b756</span><span class="plain-syntax">, </span><span class="constant-syntax">0x242070db</span><span class="plain-syntax">, </span><span class="constant-syntax">0xc1bdceee</span><span class="plain-syntax">,</span>
<span class="plain-syntax"> </span><span class="constant-syntax">0xf57c0faf</span><span class="plain-syntax">, </span><span class="constant-syntax">0x4787c62a</span><span class="plain-syntax">, </span><span class="constant-syntax">0xa8304613</span><span class="plain-syntax">, </span><span class="constant-syntax">0xfd469501</span><span class="plain-syntax">,</span>
<span class="plain-syntax"> </span><span class="constant-syntax">0x698098d8</span><span class="plain-syntax">, </span><span class="constant-syntax">0x8b44f7af</span><span class="plain-syntax">, </span><span class="constant-syntax">0xffff5bb1</span><span class="plain-syntax">, </span><span class="constant-syntax">0x895cd7be</span><span class="plain-syntax">,</span>
<span class="plain-syntax"> </span><span class="constant-syntax">0x6b901122</span><span class="plain-syntax">, </span><span class="constant-syntax">0xfd987193</span><span class="plain-syntax">, </span><span class="constant-syntax">0xa679438e</span><span class="plain-syntax">, </span><span class="constant-syntax">0x49b40821</span><span class="plain-syntax">,</span>
<span class="plain-syntax"> </span><span class="constant-syntax">0xf61e2562</span><span class="plain-syntax">, </span><span class="constant-syntax">0xc040b</span><span class="identifier-syntax">340</span><span class="plain-syntax">, </span><span class="constant-syntax">0x265e5a51</span><span class="plain-syntax">, </span><span class="constant-syntax">0xe9b6c7aa</span><span class="plain-syntax">,</span>
<span class="plain-syntax"> </span><span class="constant-syntax">0xd62f105d</span><span class="plain-syntax">, </span><span class="constant-syntax">0x02441453</span><span class="plain-syntax">, </span><span class="constant-syntax">0xd8a1e681</span><span class="plain-syntax">, </span><span class="constant-syntax">0xe7d3fbc8</span><span class="plain-syntax">,</span>
<span class="plain-syntax"> </span><span class="constant-syntax">0x21e1cde6</span><span class="plain-syntax">, </span><span class="constant-syntax">0xc33707d6</span><span class="plain-syntax">, </span><span class="constant-syntax">0xf4d50d87</span><span class="plain-syntax">, </span><span class="constant-syntax">0x455a14ed</span><span class="plain-syntax">,</span>
<span class="plain-syntax"> </span><span class="constant-syntax">0xa9e3e905</span><span class="plain-syntax">, </span><span class="constant-syntax">0xfcefa3f8</span><span class="plain-syntax">, </span><span class="constant-syntax">0x676f02d9</span><span class="plain-syntax">, </span><span class="constant-syntax">0x8d2a4c8a</span><span class="plain-syntax">,</span>
<span class="plain-syntax"> </span><span class="constant-syntax">0xfffa3942</span><span class="plain-syntax">, </span><span class="constant-syntax">0x8771f681</span><span class="plain-syntax">, </span><span class="constant-syntax">0x6d9d6122</span><span class="plain-syntax">, </span><span class="constant-syntax">0xfde5380c</span><span class="plain-syntax">,</span>
<span class="plain-syntax"> </span><span class="constant-syntax">0xa4beea44</span><span class="plain-syntax">, </span><span class="constant-syntax">0x4bdecfa9</span><span class="plain-syntax">, </span><span class="constant-syntax">0xf6bb4b60</span><span class="plain-syntax">, </span><span class="constant-syntax">0xbebfbc70</span><span class="plain-syntax">,</span>
<span class="plain-syntax"> </span><span class="constant-syntax">0x289b7ec6</span><span class="plain-syntax">, </span><span class="constant-syntax">0xeaa127fa</span><span class="plain-syntax">, </span><span class="constant-syntax">0xd4ef3085</span><span class="plain-syntax">, </span><span class="constant-syntax">0x04881d05</span><span class="plain-syntax">,</span>
<span class="plain-syntax"> </span><span class="constant-syntax">0xd9d4d039</span><span class="plain-syntax">, </span><span class="constant-syntax">0xe6db99e5</span><span class="plain-syntax">, </span><span class="constant-syntax">0x1fa27cf8</span><span class="plain-syntax">, </span><span class="constant-syntax">0xc4ac5665</span><span class="plain-syntax">,</span>
<span class="plain-syntax"> </span><span class="constant-syntax">0xf4292244</span><span class="plain-syntax">, </span><span class="constant-syntax">0x432aff97</span><span class="plain-syntax">, </span><span class="constant-syntax">0xab9423a7</span><span class="plain-syntax">, </span><span class="constant-syntax">0xfc93a039</span><span class="plain-syntax">,</span>
<span class="plain-syntax"> </span><span class="constant-syntax">0x655b59c3</span><span class="plain-syntax">, </span><span class="constant-syntax">0x8f0ccc92</span><span class="plain-syntax">, </span><span class="constant-syntax">0xffeff47d</span><span class="plain-syntax">, </span><span class="constant-syntax">0x85845dd1</span><span class="plain-syntax">,</span>
<span class="plain-syntax"> </span><span class="constant-syntax">0x6fa87e4f</span><span class="plain-syntax">, </span><span class="constant-syntax">0xfe2ce6e0</span><span class="plain-syntax">, </span><span class="constant-syntax">0xa3014314</span><span class="plain-syntax">, </span><span class="constant-syntax">0x4e0811a1</span><span class="plain-syntax">,</span>
<span class="plain-syntax"> </span><span class="constant-syntax">0xf7537e82</span><span class="plain-syntax">, </span><span class="constant-syntax">0xbd3af235</span><span class="plain-syntax">, </span><span class="constant-syntax">0x2ad7d2bb</span><span class="plain-syntax">, </span><span class="constant-syntax">0xeb86d391</span><span class="plain-syntax"> };</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">uint32_t</span><span class="plain-syntax"> </span><span class="identifier-syntax">a0</span><span class="plain-syntax"> = </span><span class="constant-syntax">0x67452301</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">uint32_t</span><span class="plain-syntax"> </span><span class="identifier-syntax">b0</span><span class="plain-syntax"> = </span><span class="constant-syntax">0xefcdab89</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">uint32_t</span><span class="plain-syntax"> </span><span class="identifier-syntax">c0</span><span class="plain-syntax"> = </span><span class="constant-syntax">0x98badcfe</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">uint32_t</span><span class="plain-syntax"> </span><span class="identifier-syntax">d0</span><span class="plain-syntax"> = </span><span class="constant-syntax">0x10325476</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">unsigned</span><span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">buffer</span><span class="plain-syntax">[64];</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">bc</span><span class="plain-syntax"> = </span><span class="constant-syntax">0</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">FILE</span><span class="plain-syntax"> *</span><span class="identifier-syntax">bin</span><span class="plain-syntax"> = </span><a href="6-bf.html#SP8" class="function-link"><span class="function-syntax">BinaryFiles::open_for_reading</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">F</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">bin</span><span class="plain-syntax"> == </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">) </span><a href="3-em.html#SP2" class="function-link"><span class="function-syntax">Errors::fatal_with_file</span></a><span class="plain-syntax">(</span><span class="string-syntax">"unable to open binary file"</span><span class="plain-syntax">, </span><span class="identifier-syntax">F</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">unsigned</span><span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">b</span><span class="plain-syntax"> = </span><span class="constant-syntax">0</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">uint64_t</span><span class="plain-syntax"> </span><span class="identifier-syntax">L</span><span class="plain-syntax"> = </span><span class="constant-syntax">0</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">while</span><span class="plain-syntax"> (</span><a href="6-bf.html#SP1" class="function-link"><span class="function-syntax">BinaryFiles::read_int8</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">bin</span><span class="plain-syntax">, &amp;</span><span class="identifier-syntax">b</span><span class="plain-syntax">)) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">mask</span><span class="plain-syntax">) &amp;&amp; (</span><span class="identifier-syntax">mask</span><span class="plain-syntax">(</span><span class="identifier-syntax">L</span><span class="plain-syntax">))) </span><span class="identifier-syntax">b</span><span class="plain-syntax"> = </span><span class="constant-syntax">0</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="6-bf.html#SP10_1" class="named-paragraph-link"><span class="named-paragraph">Process one byte of message</span><span class="named-paragraph-number">10.1</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">L</span><span class="plain-syntax">++;</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">uint64_t</span><span class="plain-syntax"> </span><span class="identifier-syntax">original_length</span><span class="plain-syntax"> = </span><span class="identifier-syntax">L</span><span class="plain-syntax">*8;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">b</span><span class="plain-syntax"> = </span><span class="constant-syntax">0x80</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="6-bf.html#SP10_1" class="named-paragraph-link"><span class="named-paragraph">Process one byte of message</span><span class="named-paragraph-number">10.1</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">L</span><span class="plain-syntax">++;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">while</span><span class="plain-syntax"> (</span><span class="identifier-syntax">L</span><span class="plain-syntax"> % </span><span class="constant-syntax">64</span><span class="plain-syntax"> != </span><span class="constant-syntax">56</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">b</span><span class="plain-syntax"> = </span><span class="constant-syntax">0</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="6-bf.html#SP10_1" class="named-paragraph-link"><span class="named-paragraph">Process one byte of message</span><span class="named-paragraph-number">10.1</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">L</span><span class="plain-syntax">++;</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">b</span><span class="plain-syntax"> = (</span><span class="identifier-syntax">original_length</span><span class="plain-syntax"> &amp; </span><span class="constant-syntax">0x00000000000000FF</span><span class="plain-syntax">) &gt;&gt; </span><span class="constant-syntax">0</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="6-bf.html#SP10_1" class="named-paragraph-link"><span class="named-paragraph">Process one byte of message</span><span class="named-paragraph-number">10.1</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">b</span><span class="plain-syntax"> = (</span><span class="identifier-syntax">original_length</span><span class="plain-syntax"> &amp; </span><span class="constant-syntax">0x000000000000FF00</span><span class="plain-syntax">) &gt;&gt; </span><span class="constant-syntax">8</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="6-bf.html#SP10_1" class="named-paragraph-link"><span class="named-paragraph">Process one byte of message</span><span class="named-paragraph-number">10.1</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">b</span><span class="plain-syntax"> = (</span><span class="identifier-syntax">original_length</span><span class="plain-syntax"> &amp; </span><span class="constant-syntax">0x0000000000FF0000</span><span class="plain-syntax">) &gt;&gt; </span><span class="constant-syntax">16</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="6-bf.html#SP10_1" class="named-paragraph-link"><span class="named-paragraph">Process one byte of message</span><span class="named-paragraph-number">10.1</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">b</span><span class="plain-syntax"> = (</span><span class="identifier-syntax">original_length</span><span class="plain-syntax"> &amp; </span><span class="constant-syntax">0x00000000FF000000</span><span class="plain-syntax">) &gt;&gt; </span><span class="constant-syntax">24</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="6-bf.html#SP10_1" class="named-paragraph-link"><span class="named-paragraph">Process one byte of message</span><span class="named-paragraph-number">10.1</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">b</span><span class="plain-syntax"> = (</span><span class="identifier-syntax">original_length</span><span class="plain-syntax"> &amp; </span><span class="constant-syntax">0x000000FF00000000</span><span class="plain-syntax">) &gt;&gt; </span><span class="constant-syntax">32</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="6-bf.html#SP10_1" class="named-paragraph-link"><span class="named-paragraph">Process one byte of message</span><span class="named-paragraph-number">10.1</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">b</span><span class="plain-syntax"> = (</span><span class="identifier-syntax">original_length</span><span class="plain-syntax"> &amp; </span><span class="constant-syntax">0x0000FF0000000000</span><span class="plain-syntax">) &gt;&gt; </span><span class="constant-syntax">40</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="6-bf.html#SP10_1" class="named-paragraph-link"><span class="named-paragraph">Process one byte of message</span><span class="named-paragraph-number">10.1</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">b</span><span class="plain-syntax"> = (</span><span class="identifier-syntax">original_length</span><span class="plain-syntax"> &amp; </span><span class="constant-syntax">0x00FF000000000000</span><span class="plain-syntax">) &gt;&gt; </span><span class="constant-syntax">48</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="6-bf.html#SP10_1" class="named-paragraph-link"><span class="named-paragraph">Process one byte of message</span><span class="named-paragraph-number">10.1</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">b</span><span class="plain-syntax"> = (</span><span class="identifier-syntax">original_length</span><span class="plain-syntax"> &amp; </span><span class="constant-syntax">0xFF00000000000000</span><span class="plain-syntax">) &gt;&gt; </span><span class="constant-syntax">56</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="6-bf.html#SP10_1" class="named-paragraph-link"><span class="named-paragraph">Process one byte of message</span><span class="named-paragraph-number">10.1</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">"%02x%02x%02x%02x"</span><span class="plain-syntax">,</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">a0</span><span class="plain-syntax"> % </span><span class="constant-syntax">0x100</span><span class="plain-syntax">, (</span><span class="identifier-syntax">a0</span><span class="plain-syntax"> &gt;&gt; </span><span class="constant-syntax">8</span><span class="plain-syntax">) % </span><span class="constant-syntax">0x100</span><span class="plain-syntax">, (</span><span class="identifier-syntax">a0</span><span class="plain-syntax"> &gt;&gt; </span><span class="constant-syntax">16</span><span class="plain-syntax">) % </span><span class="constant-syntax">0x100</span><span class="plain-syntax">, (</span><span class="identifier-syntax">a0</span><span class="plain-syntax"> &gt;&gt; </span><span class="constant-syntax">24</span><span class="plain-syntax">) % </span><span class="constant-syntax">0x100</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">"%02x%02x%02x%02x"</span><span class="plain-syntax">,</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">b0</span><span class="plain-syntax"> % </span><span class="constant-syntax">0x100</span><span class="plain-syntax">, (</span><span class="identifier-syntax">b0</span><span class="plain-syntax"> &gt;&gt; </span><span class="constant-syntax">8</span><span class="plain-syntax">) % </span><span class="constant-syntax">0x100</span><span class="plain-syntax">, (</span><span class="identifier-syntax">b0</span><span class="plain-syntax"> &gt;&gt; </span><span class="constant-syntax">16</span><span class="plain-syntax">) % </span><span class="constant-syntax">0x100</span><span class="plain-syntax">, (</span><span class="identifier-syntax">b0</span><span class="plain-syntax"> &gt;&gt; </span><span class="constant-syntax">24</span><span class="plain-syntax">) % </span><span class="constant-syntax">0x100</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">"%02x%02x%02x%02x"</span><span class="plain-syntax">,</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">c0</span><span class="plain-syntax"> % </span><span class="constant-syntax">0x100</span><span class="plain-syntax">, (</span><span class="identifier-syntax">c0</span><span class="plain-syntax"> &gt;&gt; </span><span class="constant-syntax">8</span><span class="plain-syntax">) % </span><span class="constant-syntax">0x100</span><span class="plain-syntax">, (</span><span class="identifier-syntax">c0</span><span class="plain-syntax"> &gt;&gt; </span><span class="constant-syntax">16</span><span class="plain-syntax">) % </span><span class="constant-syntax">0x100</span><span class="plain-syntax">, (</span><span class="identifier-syntax">c0</span><span class="plain-syntax"> &gt;&gt; </span><span class="constant-syntax">24</span><span class="plain-syntax">) % </span><span class="constant-syntax">0x100</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">"%02x%02x%02x%02x"</span><span class="plain-syntax">,</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">d0</span><span class="plain-syntax"> % </span><span class="constant-syntax">0x100</span><span class="plain-syntax">, (</span><span class="identifier-syntax">d0</span><span class="plain-syntax"> &gt;&gt; </span><span class="constant-syntax">8</span><span class="plain-syntax">) % </span><span class="constant-syntax">0x100</span><span class="plain-syntax">, (</span><span class="identifier-syntax">d0</span><span class="plain-syntax"> &gt;&gt; </span><span class="constant-syntax">16</span><span class="plain-syntax">) % </span><span class="constant-syntax">0x100</span><span class="plain-syntax">, (</span><span class="identifier-syntax">d0</span><span class="plain-syntax"> &gt;&gt; </span><span class="constant-syntax">24</span><span class="plain-syntax">) % </span><span class="constant-syntax">0x100</span><span class="plain-syntax">);</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP10_1" class="paragraph-anchor"></a><b>&#167;10.1. </b><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Process one byte of message</span><span class="named-paragraph-number">10.1</span></span><span class="comment-syntax"> =</span>
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> </span><span class="identifier-syntax">buffer</span><span class="plain-syntax">[</span><span class="identifier-syntax">bc</span><span class="plain-syntax">++] = (</span><span class="identifier-syntax">b</span><span class="plain-syntax"> % </span><span class="constant-syntax">0x100</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">bc</span><span class="plain-syntax"> == </span><span class="constant-syntax">64</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">bc</span><span class="plain-syntax"> = </span><span class="constant-syntax">0</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">uint32_t</span><span class="plain-syntax"> </span><span class="identifier-syntax">M</span><span class="plain-syntax">[16];</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">for</span><span class="plain-syntax"> (</span><span class="identifier-syntax">uint32_t</span><span class="plain-syntax"> </span><span class="identifier-syntax">i</span><span class="plain-syntax">=0; </span><span class="identifier-syntax">i</span><span class="plain-syntax">&lt;16; </span><span class="identifier-syntax">i</span><span class="plain-syntax">++)</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">M</span><span class="plain-syntax">[</span><span class="identifier-syntax">i</span><span class="plain-syntax">] = </span><span class="identifier-syntax">buffer</span><span class="plain-syntax">[</span><span class="identifier-syntax">i</span><span class="plain-syntax">*4+3]*</span><span class="constant-syntax">0x1000000</span><span class="plain-syntax"> + </span><span class="identifier-syntax">buffer</span><span class="plain-syntax">[</span><span class="identifier-syntax">i</span><span class="plain-syntax">*4+2]*</span><span class="constant-syntax">0x10000</span><span class="plain-syntax"> +</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">buffer</span><span class="plain-syntax">[</span><span class="identifier-syntax">i</span><span class="plain-syntax">*4+1]*</span><span class="constant-syntax">0x100</span><span class="plain-syntax"> + </span><span class="identifier-syntax">buffer</span><span class="plain-syntax">[</span><span class="identifier-syntax">i</span><span class="plain-syntax">*4+0];</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">uint32_t</span><span class="plain-syntax"> </span><span class="identifier-syntax">A</span><span class="plain-syntax"> = </span><span class="identifier-syntax">a0</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">uint32_t</span><span class="plain-syntax"> </span><span class="identifier-syntax">B</span><span class="plain-syntax"> = </span><span class="identifier-syntax">b0</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">uint32_t</span><span class="plain-syntax"> </span><span class="identifier-syntax">C</span><span class="plain-syntax"> = </span><span class="identifier-syntax">c0</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">uint32_t</span><span class="plain-syntax"> </span><span class="identifier-syntax">D</span><span class="plain-syntax"> = </span><span class="identifier-syntax">d0</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">for</span><span class="plain-syntax"> (</span><span class="identifier-syntax">uint32_t</span><span class="plain-syntax"> </span><span class="identifier-syntax">i</span><span class="plain-syntax">=0; </span><span class="identifier-syntax">i</span><span class="plain-syntax">&lt;64; </span><span class="identifier-syntax">i</span><span class="plain-syntax">++) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">uint32_t</span><span class="plain-syntax"> </span><span class="identifier-syntax">F</span><span class="plain-syntax">, </span><span class="identifier-syntax">g</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">i</span><span class="plain-syntax"> &lt; </span><span class="constant-syntax">16</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">F</span><span class="plain-syntax"> = (</span><span class="identifier-syntax">B</span><span class="plain-syntax"> &amp; </span><span class="identifier-syntax">C</span><span class="plain-syntax">) | ((~ </span><span class="identifier-syntax">B</span><span class="plain-syntax">) &amp; </span><span class="identifier-syntax">D</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">g</span><span class="plain-syntax"> = </span><span class="identifier-syntax">i</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> } </span><span class="reserved-syntax">else</span><span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">i</span><span class="plain-syntax"> &lt; </span><span class="constant-syntax">32</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">F</span><span class="plain-syntax"> = (</span><span class="identifier-syntax">D</span><span class="plain-syntax"> &amp; </span><span class="identifier-syntax">B</span><span class="plain-syntax">) | ((~ </span><span class="identifier-syntax">D</span><span class="plain-syntax">) &amp; </span><span class="identifier-syntax">C</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">g</span><span class="plain-syntax"> = (5*</span><span class="identifier-syntax">i</span><span class="plain-syntax"> + </span><span class="constant-syntax">1</span><span class="plain-syntax">) % </span><span class="constant-syntax">16</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> } </span><span class="reserved-syntax">else</span><span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">i</span><span class="plain-syntax"> &lt; </span><span class="constant-syntax">48</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">F</span><span class="plain-syntax"> = </span><span class="identifier-syntax">B</span><span class="plain-syntax"> ^ </span><span class="identifier-syntax">C</span><span class="plain-syntax"> ^ </span><span class="identifier-syntax">D</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">g</span><span class="plain-syntax"> = (3*</span><span class="identifier-syntax">i</span><span class="plain-syntax"> + </span><span class="constant-syntax">5</span><span class="plain-syntax">) % </span><span class="constant-syntax">16</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> } </span><span class="reserved-syntax">else</span><span class="plain-syntax"> {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">F</span><span class="plain-syntax"> = </span><span class="identifier-syntax">C</span><span class="plain-syntax"> ^ (</span><span class="identifier-syntax">B</span><span class="plain-syntax"> | (~ </span><span class="identifier-syntax">D</span><span class="plain-syntax">));</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">g</span><span class="plain-syntax"> = (7*</span><span class="identifier-syntax">i</span><span class="plain-syntax">) % </span><span class="constant-syntax">16</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">F</span><span class="plain-syntax"> += </span><span class="identifier-syntax">A</span><span class="plain-syntax"> + </span><span class="identifier-syntax">K</span><span class="plain-syntax">[</span><span class="identifier-syntax">i</span><span class="plain-syntax">] + </span><span class="identifier-syntax">M</span><span class="plain-syntax">[</span><span class="identifier-syntax">g</span><span class="plain-syntax">];</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">A</span><span class="plain-syntax"> = </span><span class="identifier-syntax">D</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">D</span><span class="plain-syntax"> = </span><span class="identifier-syntax">C</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">C</span><span class="plain-syntax"> = </span><span class="identifier-syntax">B</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">B</span><span class="plain-syntax"> = </span><span class="identifier-syntax">B</span><span class="plain-syntax"> + </span><a href="6-bf.html#SP11" class="function-link"><span class="function-syntax">BinaryFiles::rotate</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">F</span><span class="plain-syntax">, </span><span class="identifier-syntax">s</span><span class="plain-syntax">[</span><span class="identifier-syntax">i</span><span class="plain-syntax">]);</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">a0</span><span class="plain-syntax"> += </span><span class="identifier-syntax">A</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">b0</span><span class="plain-syntax"> += </span><span class="identifier-syntax">B</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">c0</span><span class="plain-syntax"> += </span><span class="identifier-syntax">C</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">d0</span><span class="plain-syntax"> += </span><span class="identifier-syntax">D</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> }</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="6-bf.html#SP10">&#167;10</a> (11 times).</li></ul>
<p class="commentary firstcommentary"><a id="SP11" class="paragraph-anchor"></a><b>&#167;11. </b>This is a C-compiler safe way to rotate a 32-bit unsigned integer left
by <span class="extract"><span class="extract-syntax">shift</span></span> number of bits. Enjoy:
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="identifier-syntax">uint32_t</span><span class="plain-syntax"> </span><span class="function-syntax">BinaryFiles::rotate</span><button class="popup" onclick="togglePopup('usagePopup14')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup14">Usage of <span class="code-font"><span class="function-syntax">BinaryFiles::rotate</span></span>:<br/><a href="6-bf.html#SP10_1">&#167;10.1</a></span></button><span class="plain-syntax">(</span><span class="identifier-syntax">uint32_t</span><span class="plain-syntax"> </span><span class="identifier-syntax">value</span><span class="plain-syntax">, </span><span class="identifier-syntax">uint32_t</span><span class="plain-syntax"> </span><span class="identifier-syntax">shift</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">shift</span><span class="plain-syntax"> &amp;= </span><span class="reserved-syntax">sizeof</span><span class="plain-syntax">(</span><span class="identifier-syntax">value</span><span class="plain-syntax">)*8 - </span><span class="constant-syntax">1</span><span class="plain-syntax">) == </span><span class="constant-syntax">0</span><span class="plain-syntax">) </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">value</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> (</span><span class="identifier-syntax">value</span><span class="plain-syntax"> &lt;&lt; </span><span class="identifier-syntax">shift</span><span class="plain-syntax">) | (</span><span class="identifier-syntax">value</span><span class="plain-syntax"> &gt;&gt; (</span><span class="reserved-syntax">sizeof</span><span class="plain-syntax">(</span><span class="identifier-syntax">value</span><span class="plain-syntax">)*8 - </span><span class="identifier-syntax">shift</span><span class="plain-syntax">));</span>
<span class="plain-syntax">}</span>
</pre>
<nav role="progress"><div class="progresscontainer">
<ul class="progressbar"><li class="progressprev"><a href="5-ee.html">&#10094;</a></li><li class="progresschapter"><a href="P-abgtf.html">P</a></li><li class="progresschapter"><a href="1-fm.html">1</a></li><li class="progresschapter"><a href="2-dl.html">2</a></li><li class="progresschapter"><a href="3-em.html">3</a></li><li class="progresschapter"><a href="4-chr.html">4</a></li><li class="progresschapter"><a href="5-htm.html">5</a></li><li class="progresscurrentchapter">6</li><li class="progresscurrent">bf</li><li class="progresssection"><a href="6-id.html">id</a></li><li class="progresssection"><a href="6-sd.html">sd</a></li><li class="progresschapter"><a href="7-vn.html">7</a></li><li class="progresschapter"><a href="8-ws.html">8</a></li><li class="progressnext"><a href="6-id.html">&#10095;</a></li></ul></div>
</nav><!--End of weave-->

View file

@ -61,7 +61,7 @@ MathJax = {
<p class="commentary firstcommentary"><a id="SP1" class="paragraph-anchor"></a><b>&#167;1. Introduction. </b>The Foundation module supplies some of the conveniences of more modern
programming languages to ANSI C. It offers the usual stuff of standard
libraries everywhere: memory management, collection classes, filename and file
system accesss, regular-expression matching and so on, and it does so while
system access, regular-expression matching and so on, and it does so while
abstracting away differences between operating systems (Windows, Linux,
Unix, MacOS, Android and so on).
</p>
@ -481,7 +481,8 @@ working directory, and the installation directory for a program.
</p>
<p class="commentary firstcommentary"><a id="SP17" class="paragraph-anchor"></a><b>&#167;17. </b><a href="6-bf.html" class="internal">Binary Files</a> does the tedious work of writing binary data while allowing
for endian-ness.
for endian-ness; and it can also compute md5 hashes of binary files, which is
useful for testing the correctness of our tools.
</p>
<p class="commentary firstcommentary"><a id="SP18" class="paragraph-anchor"></a><b>&#167;18. </b><a href="4-tf.html" class="internal">Text Files</a> allows us to read text files. Its most useful function is

Binary file not shown.

View file

@ -236,3 +236,149 @@ int BinaryFiles::copy(filename *from, filename *to, int suppress_error) {
BinaryFiles::close(FROM); BinaryFiles::close(TO);
return size;
}
@h MD5 hash computation.
Though now seen as insecure from a cryptographic point of view, Message Digest 5,
a form of checksum created by Ronald Rivest in 1992, remains very useful as a
way to compare files quickly, at least when we're sure nobody is being malicious.
There are thousands of amateur implementations, most of them, like this one,
paraphrased from the pseudocode at the Wikipedia page. The |mask| function allows
certain fixed byte positions in the file to be considered as if they were zero bytes,
which is helpful when testing comparing files whose headers change in uninteresting
ways. If |mask| is |NULL|, or always returns |FALSE|, then the hash computed is
exactly the canonical md5.
The code below is about as enigmatic as a page of well-meaning code can be, but
that's down to the algorithm itself. The |K| array hold bits drawn from the sines
of the integers 1 to 64: sines computed in radians, so that in a sense the md5
algorithm relies on the irrationality of $\pi$ to make these so unpredictable.
At any rate, the magic numbers below are all drawn from RFC 1321.
=
void BinaryFiles::md5(OUTPUT_STREAM, filename *F, int (*mask)(uint64_t)) {
uint32_t s[64] = {
7, 12, 17, 22, 7, 12, 17, 22, 7, 12, 17, 22, 7, 12, 17, 22,
5, 9, 14, 20, 5, 9, 14, 20, 5, 9, 14, 20, 5, 9, 14, 20,
4, 11, 16, 23, 4, 11, 16, 23, 4, 11, 16, 23, 4, 11, 16, 23,
6, 10, 15, 21, 6, 10, 15, 21, 6, 10, 15, 21, 6, 10, 15, 21 };
uint32_t K[64] = {
0xd76aa478, 0xe8c7b756, 0x242070db, 0xc1bdceee,
0xf57c0faf, 0x4787c62a, 0xa8304613, 0xfd469501,
0x698098d8, 0x8b44f7af, 0xffff5bb1, 0x895cd7be,
0x6b901122, 0xfd987193, 0xa679438e, 0x49b40821,
0xf61e2562, 0xc040b340, 0x265e5a51, 0xe9b6c7aa,
0xd62f105d, 0x02441453, 0xd8a1e681, 0xe7d3fbc8,
0x21e1cde6, 0xc33707d6, 0xf4d50d87, 0x455a14ed,
0xa9e3e905, 0xfcefa3f8, 0x676f02d9, 0x8d2a4c8a,
0xfffa3942, 0x8771f681, 0x6d9d6122, 0xfde5380c,
0xa4beea44, 0x4bdecfa9, 0xf6bb4b60, 0xbebfbc70,
0x289b7ec6, 0xeaa127fa, 0xd4ef3085, 0x04881d05,
0xd9d4d039, 0xe6db99e5, 0x1fa27cf8, 0xc4ac5665,
0xf4292244, 0x432aff97, 0xab9423a7, 0xfc93a039,
0x655b59c3, 0x8f0ccc92, 0xffeff47d, 0x85845dd1,
0x6fa87e4f, 0xfe2ce6e0, 0xa3014314, 0x4e0811a1,
0xf7537e82, 0xbd3af235, 0x2ad7d2bb, 0xeb86d391 };
uint32_t a0 = 0x67452301;
uint32_t b0 = 0xefcdab89;
uint32_t c0 = 0x98badcfe;
uint32_t d0 = 0x10325476;
unsigned int buffer[64];
int bc = 0;
FILE *bin = BinaryFiles::open_for_reading(F);
if (bin == NULL) Errors::fatal_with_file("unable to open binary file", F);
unsigned int b = 0;
uint64_t L = 0;
while (BinaryFiles::read_int8(bin, &b)) {
if ((mask) && (mask(L))) b = 0;
@<Process one byte of message@>;
L++;
}
uint64_t original_length = L*8;
b = 0x80;
@<Process one byte of message@>;
L++;
while (L % 64 != 56) {
b = 0;
@<Process one byte of message@>;
L++;
}
b = (original_length & 0x00000000000000FF) >> 0;
@<Process one byte of message@>;
b = (original_length & 0x000000000000FF00) >> 8;
@<Process one byte of message@>;
b = (original_length & 0x0000000000FF0000) >> 16;
@<Process one byte of message@>;
b = (original_length & 0x00000000FF000000) >> 24;
@<Process one byte of message@>;
b = (original_length & 0x000000FF00000000) >> 32;
@<Process one byte of message@>;
b = (original_length & 0x0000FF0000000000) >> 40;
@<Process one byte of message@>;
b = (original_length & 0x00FF000000000000) >> 48;
@<Process one byte of message@>;
b = (original_length & 0xFF00000000000000) >> 56;
@<Process one byte of message@>;
WRITE("%02x%02x%02x%02x",
a0 % 0x100, (a0 >> 8) % 0x100, (a0 >> 16) % 0x100, (a0 >> 24) % 0x100);
WRITE("%02x%02x%02x%02x",
b0 % 0x100, (b0 >> 8) % 0x100, (b0 >> 16) % 0x100, (b0 >> 24) % 0x100);
WRITE("%02x%02x%02x%02x",
c0 % 0x100, (c0 >> 8) % 0x100, (c0 >> 16) % 0x100, (c0 >> 24) % 0x100);
WRITE("%02x%02x%02x%02x",
d0 % 0x100, (d0 >> 8) % 0x100, (d0 >> 16) % 0x100, (d0 >> 24) % 0x100);
}
@<Process one byte of message@> =
buffer[bc++] = (b % 0x100);
if (bc == 64) {
bc = 0;
uint32_t M[16];
for (uint32_t i=0; i<16; i++)
M[i] = buffer[i*4+3]*0x1000000 + buffer[i*4+2]*0x10000 +
buffer[i*4+1]*0x100 + buffer[i*4+0];
uint32_t A = a0;
uint32_t B = b0;
uint32_t C = c0;
uint32_t D = d0;
for (uint32_t i=0; i<64; i++) {
uint32_t F, g;
if (i < 16) {
F = (B & C) | ((~ B) & D);
g = i;
} else if (i < 32) {
F = (D & B) | ((~ D) & C);
g = (5*i + 1) % 16;
} else if (i < 48) {
F = B ^ C ^ D;
g = (3*i + 5) % 16;
} else {
F = C ^ (B | (~ D));
g = (7*i) % 16;
}
F += A + K[i] + M[g];
A = D;
D = C;
C = B;
B = B + BinaryFiles::rotate(F, s[i]);
}
a0 += A;
b0 += B;
c0 += C;
d0 += D;
}
@ This is a C-compiler safe way to rotate a 32-bit unsigned integer left
by |shift| number of bits. Enjoy:
=
uint32_t BinaryFiles::rotate(uint32_t value, uint32_t shift) {
if ((shift &= sizeof(value)*8 - 1) == 0) return value;
return (value << shift) | (value >> (sizeof(value)*8 - shift));
}

View file

@ -6,7 +6,7 @@ Notes on getting started with the Foundation library.
The Foundation module supplies some of the conveniences of more modern
programming languages to ANSI C. It offers the usual stuff of standard
libraries everywhere: memory management, collection classes, filename and file
system accesss, regular-expression matching and so on, and it does so while
system access, regular-expression matching and so on, and it does so while
abstracting away differences between operating systems (Windows, Linux,
Unix, MacOS, Android and so on).
@ -350,7 +350,8 @@ See //Pathnames// for how to access the user's home directory, the current
working directory, and the installation directory for a program.
@ //Binary Files// does the tedious work of writing binary data while allowing
for endian-ness.
for endian-ness; and it can also compute md5 hashes of binary files, which is
useful for testing the correctness of our tools.
@ //Text Files// allows us to read text files. Its most useful function is
//TextFiles::read//, which opens a file, can print an error if it doesn't