mirror of https://github.com/python/peps
367 lines
23 KiB
HTML
367 lines
23 KiB
HTML
|
||
<!DOCTYPE html>
|
||
<html lang="en">
|
||
<head>
|
||
<meta charset="utf-8">
|
||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||
<meta name="color-scheme" content="light dark">
|
||
<title>PEP 452 – API for Cryptographic Hash Functions v2.0 | peps.python.org</title>
|
||
<link rel="shortcut icon" href="../_static/py.png">
|
||
<link rel="canonical" href="https://peps.python.org/pep-0452/">
|
||
<link rel="stylesheet" href="../_static/style.css" type="text/css">
|
||
<link rel="stylesheet" href="../_static/mq.css" type="text/css">
|
||
<link rel="stylesheet" href="../_static/pygments.css" type="text/css" media="(prefers-color-scheme: light)" id="pyg-light">
|
||
<link rel="stylesheet" href="../_static/pygments_dark.css" type="text/css" media="(prefers-color-scheme: dark)" id="pyg-dark">
|
||
<link rel="alternate" type="application/rss+xml" title="Latest PEPs" href="https://peps.python.org/peps.rss">
|
||
<meta property="og:title" content='PEP 452 – API for Cryptographic Hash Functions v2.0 | peps.python.org'>
|
||
<meta property="og:type" content="website">
|
||
<meta property="og:url" content="https://peps.python.org/pep-0452/">
|
||
<meta property="og:site_name" content="Python Enhancement Proposals (PEPs)">
|
||
<meta property="og:image" content="https://peps.python.org/_static/og-image.png">
|
||
<meta property="og:image:alt" content="Python PEPs">
|
||
<meta property="og:image:width" content="200">
|
||
<meta property="og:image:height" content="200">
|
||
<meta name="description" content="Python Enhancement Proposals (PEPs)">
|
||
<meta name="theme-color" content="#3776ab">
|
||
</head>
|
||
<body>
|
||
|
||
<svg xmlns="http://www.w3.org/2000/svg" style="display: none;">
|
||
<symbol id="svg-sun-half" viewBox="0 0 24 24" pointer-events="all">
|
||
<title>Following system colour scheme</title>
|
||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none"
|
||
stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
|
||
<circle cx="12" cy="12" r="9"></circle>
|
||
<path d="M12 3v18m0-12l4.65-4.65M12 14.3l7.37-7.37M12 19.6l8.85-8.85"></path>
|
||
</svg>
|
||
</symbol>
|
||
<symbol id="svg-moon" viewBox="0 0 24 24" pointer-events="all">
|
||
<title>Selected dark colour scheme</title>
|
||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none"
|
||
stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
|
||
<path stroke="none" d="M0 0h24v24H0z" fill="none"></path>
|
||
<path d="M12 3c.132 0 .263 0 .393 0a7.5 7.5 0 0 0 7.92 12.446a9 9 0 1 1 -8.313 -12.454z"></path>
|
||
</svg>
|
||
</symbol>
|
||
<symbol id="svg-sun" viewBox="0 0 24 24" pointer-events="all">
|
||
<title>Selected light colour scheme</title>
|
||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none"
|
||
stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
|
||
<circle cx="12" cy="12" r="5"></circle>
|
||
<line x1="12" y1="1" x2="12" y2="3"></line>
|
||
<line x1="12" y1="21" x2="12" y2="23"></line>
|
||
<line x1="4.22" y1="4.22" x2="5.64" y2="5.64"></line>
|
||
<line x1="18.36" y1="18.36" x2="19.78" y2="19.78"></line>
|
||
<line x1="1" y1="12" x2="3" y2="12"></line>
|
||
<line x1="21" y1="12" x2="23" y2="12"></line>
|
||
<line x1="4.22" y1="19.78" x2="5.64" y2="18.36"></line>
|
||
<line x1="18.36" y1="5.64" x2="19.78" y2="4.22"></line>
|
||
</svg>
|
||
</symbol>
|
||
</svg>
|
||
<script>
|
||
|
||
document.documentElement.dataset.colour_scheme = localStorage.getItem("colour_scheme") || "auto"
|
||
</script>
|
||
<section id="pep-page-section">
|
||
<header>
|
||
<h1>Python Enhancement Proposals</h1>
|
||
<ul class="breadcrumbs">
|
||
<li><a href="https://www.python.org/" title="The Python Programming Language">Python</a> » </li>
|
||
<li><a href="../pep-0000/">PEP Index</a> » </li>
|
||
<li>PEP 452</li>
|
||
</ul>
|
||
<button id="colour-scheme-cycler" onClick="setColourScheme(nextColourScheme())">
|
||
<svg aria-hidden="true" class="colour-scheme-icon-when-auto"><use href="#svg-sun-half"></use></svg>
|
||
<svg aria-hidden="true" class="colour-scheme-icon-when-dark"><use href="#svg-moon"></use></svg>
|
||
<svg aria-hidden="true" class="colour-scheme-icon-when-light"><use href="#svg-sun"></use></svg>
|
||
<span class="visually-hidden">Toggle light / dark / auto colour theme</span>
|
||
</button>
|
||
</header>
|
||
<article>
|
||
<section id="pep-content">
|
||
<h1 class="page-title">PEP 452 – API for Cryptographic Hash Functions v2.0</h1>
|
||
<dl class="rfc2822 field-list simple">
|
||
<dt class="field-odd">Author<span class="colon">:</span></dt>
|
||
<dd class="field-odd">A.M. Kuchling <amk at amk.ca>, Christian Heimes <christian at python.org></dd>
|
||
<dt class="field-even">Status<span class="colon">:</span></dt>
|
||
<dd class="field-even"><abbr title="Accepted and implementation complete, or no longer active">Final</abbr></dd>
|
||
<dt class="field-odd">Type<span class="colon">:</span></dt>
|
||
<dd class="field-odd"><abbr title="Non-normative PEP containing background, guidelines or other information relevant to the Python ecosystem">Informational</abbr></dd>
|
||
<dt class="field-even">Created<span class="colon">:</span></dt>
|
||
<dd class="field-even">15-Aug-2013</dd>
|
||
<dt class="field-odd">Post-History<span class="colon">:</span></dt>
|
||
<dd class="field-odd"><p></p></dd>
|
||
<dt class="field-even">Replaces<span class="colon">:</span></dt>
|
||
<dd class="field-even"><a class="reference external" href="../pep-0247/">247</a></dd>
|
||
</dl>
|
||
<hr class="docutils" />
|
||
<section id="contents">
|
||
<details><summary>Table of Contents</summary><ul class="simple">
|
||
<li><a class="reference internal" href="#abstract">Abstract</a></li>
|
||
<li><a class="reference internal" href="#specification">Specification</a></li>
|
||
<li><a class="reference internal" href="#rationale">Rationale</a></li>
|
||
<li><a class="reference internal" href="#changes-from-version-1-0-to-version-2-0">Changes from Version 1.0 to Version 2.0</a></li>
|
||
<li><a class="reference internal" href="#recommended-names-for-common-hashing-algorithms">Recommended names for common hashing algorithms</a></li>
|
||
<li><a class="reference internal" href="#changes">Changes</a></li>
|
||
<li><a class="reference internal" href="#acknowledgements">Acknowledgements</a></li>
|
||
<li><a class="reference internal" href="#copyright">Copyright</a></li>
|
||
</ul>
|
||
</details></section>
|
||
<section id="abstract">
|
||
<h2><a class="toc-backref" href="#abstract" role="doc-backlink">Abstract</a></h2>
|
||
<p>There are several different modules available that implement
|
||
cryptographic hashing algorithms such as MD5 or SHA. This
|
||
document specifies a standard API for such algorithms, to make it
|
||
easier to switch between different implementations.</p>
|
||
</section>
|
||
<section id="specification">
|
||
<h2><a class="toc-backref" href="#specification" role="doc-backlink">Specification</a></h2>
|
||
<p>All hashing modules should present the same interface. Additional
|
||
methods or variables can be added, but those described in this
|
||
document should always be present.</p>
|
||
<p>Hash function modules define one function:</p>
|
||
<p><code class="docutils literal notranslate"><span class="pre">new([string])</span>            <span class="pre">(unkeyed</span> <span class="pre">hashes)</span></code></p>
|
||
<dl>
|
||
<dt><code class="docutils literal notranslate"><span class="pre">new(key,</span> <span class="pre">[string],</span> <span class="pre">[digestmod])</span>    <span class="pre">(keyed</span> <span class="pre">hashes)</span></code></dt><dd>Create a new hashing object and return it. The first form is
|
||
for hashes that are unkeyed, such as MD5 or SHA. For keyed
|
||
hashes such as HMAC, ‘key’ is a required parameter containing
|
||
a string giving the key to use. In both cases, the optional
|
||
‘string’ parameter, if supplied, will be immediately hashed
|
||
into the object’s starting state, as if <code class="docutils literal notranslate"><span class="pre">obj.update(string)</span></code> was
|
||
called.<p>After creating a hashing object, arbitrary bytes can be fed
|
||
into the object using its <code class="docutils literal notranslate"><span class="pre">update()</span></code> method, and the hash value
|
||
can be obtained at any time by calling the object’s <code class="docutils literal notranslate"><span class="pre">digest()</span></code>
|
||
method.</p>
|
||
<p>Although the parameter is called ‘string’, hashing objects operate
|
||
on 8-bit data only. Both ‘key’ and ‘string’ must be a bytes-like
|
||
object (bytes, bytearray…). A hashing object may support
|
||
one-dimensional, contiguous buffers as argument, too. Text
|
||
(unicode) is no longer supported in Python 3.x. Python 2.x
|
||
implementations may take ASCII-only unicode as argument, but
|
||
portable code should not rely on the feature.</p>
|
||
<p>Arbitrary additional keyword arguments can be added to this
|
||
function, but if they’re not supplied, sensible default values
|
||
should be used. For example, ‘rounds’ and ‘digest_size’
|
||
keywords could be added for a hash function which supports a
|
||
variable number of rounds and several different output sizes,
|
||
and they should default to values believed to be secure.</p>
|
||
</dd>
|
||
</dl>
|
||
<p>Hash function modules define one variable:</p>
|
||
<dl class="simple">
|
||
<dt><code class="docutils literal notranslate"><span class="pre">digest_size</span></code></dt><dd>An integer value; the size of the digest produced by the
|
||
hashing objects created by this module, measured in bytes.
|
||
You could also obtain this value by creating a sample object
|
||
and accessing its ‘digest_size’ attribute, but it can be
|
||
convenient to have this value available from the module.
|
||
Hashes with a variable output size will set this variable to
|
||
None.</dd>
|
||
</dl>
|
||
<p>Hashing objects require the following attribute:</p>
|
||
<dl class="simple">
|
||
<dt><code class="docutils literal notranslate"><span class="pre">digest_size</span></code></dt><dd>This attribute is identical to the module-level digest_size
|
||
variable, measuring the size of the digest produced by the
|
||
hashing object, measured in bytes. If the hash has a variable
|
||
output size, this output size must be chosen when the hashing
|
||
object is created, and this attribute must contain the
|
||
selected size. Therefore, <code class="docutils literal notranslate"><span class="pre">None</span></code> is <strong>not</strong> a legal value for this
|
||
attribute.</dd>
|
||
<dt><code class="docutils literal notranslate"><span class="pre">block_size</span></code></dt><dd>An integer value or <code class="docutils literal notranslate"><span class="pre">NotImplemented</span></code>; the internal block size
|
||
of the hash algorithm in bytes. The block size is used by the
|
||
HMAC module to pad the secret key to <code class="docutils literal notranslate"><span class="pre">digest_size</span></code> or to hash the
|
||
secret key if it is longer than <code class="docutils literal notranslate"><span class="pre">digest_size</span></code>. If no HMAC
|
||
algorithm is standardized for the hash algorithm, return
|
||
<code class="docutils literal notranslate"><span class="pre">NotImplemented</span></code> instead.</dd>
|
||
<dt><code class="docutils literal notranslate"><span class="pre">name</span></code></dt><dd>A text string value; the canonical, lowercase name of the hashing
|
||
algorithm. The name should be a suitable parameter for
|
||
<code class="docutils literal notranslate"><span class="pre">hashlib.new</span></code>.</dd>
|
||
</dl>
|
||
<p>Hashing objects require the following methods:</p>
|
||
<dl class="simple">
|
||
<dt><code class="docutils literal notranslate"><span class="pre">copy()</span></code></dt><dd>Return a separate copy of this hashing object. An update to
|
||
this copy won’t affect the original object.</dd>
|
||
<dt><code class="docutils literal notranslate"><span class="pre">digest()</span></code></dt><dd>Return the hash value of this hashing object as a bytes
|
||
containing 8-bit data. The object is not altered in any way
|
||
by this function; you can continue updating the object after
|
||
calling this function.</dd>
|
||
<dt><code class="docutils literal notranslate"><span class="pre">hexdigest()</span></code></dt><dd>Return the hash value of this hashing object as a string
|
||
containing hexadecimal digits. Lowercase letters should be used
|
||
for the digits ‘a’ through ‘f’. Like the <code class="docutils literal notranslate"><span class="pre">.digest()</span></code> method, this
|
||
method mustn’t alter the object.</dd>
|
||
<dt><code class="docutils literal notranslate"><span class="pre">update(string)</span></code></dt><dd>Hash bytes-like ‘string’ into the current state of the hashing
|
||
object. <code class="docutils literal notranslate"><span class="pre">update()</span></code> can be called any number of times during a
|
||
hashing object’s lifetime.</dd>
|
||
</dl>
|
||
<p>Hashing modules can define additional module-level functions or
|
||
object methods and still be compliant with this specification.</p>
|
||
<p>Here’s an example, using a module named ‘MD5’:</p>
|
||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="gp">>>> </span><span class="kn">import</span> <span class="nn">hashlib</span>
|
||
<span class="gp">>>> </span><span class="kn">from</span> <span class="nn">Crypto.Hash</span> <span class="kn">import</span> <span class="n">MD5</span>
|
||
<span class="gp">>>> </span><span class="n">m</span> <span class="o">=</span> <span class="n">MD5</span><span class="o">.</span><span class="n">new</span><span class="p">()</span>
|
||
<span class="gp">>>> </span><span class="nb">isinstance</span><span class="p">(</span><span class="n">m</span><span class="p">,</span> <span class="n">hashlib</span><span class="o">.</span><span class="n">CryptoHash</span><span class="p">)</span>
|
||
<span class="go">True</span>
|
||
<span class="gp">>>> </span><span class="n">m</span><span class="o">.</span><span class="n">name</span>
|
||
<span class="go">'md5'</span>
|
||
<span class="gp">>>> </span><span class="n">m</span><span class="o">.</span><span class="n">digest_size</span>
|
||
<span class="go">16</span>
|
||
<span class="gp">>>> </span><span class="n">m</span><span class="o">.</span><span class="n">block_size</span>
|
||
<span class="go">64</span>
|
||
<span class="gp">>>> </span><span class="n">m</span><span class="o">.</span><span class="n">update</span><span class="p">(</span><span class="sa">b</span><span class="s1">'abc'</span><span class="p">)</span>
|
||
<span class="gp">>>> </span><span class="n">m</span><span class="o">.</span><span class="n">digest</span><span class="p">()</span>
|
||
<span class="go">b'\x90\x01P\x98<\xd2O\xb0\xd6\x96?}(\xe1\x7fr'</span>
|
||
<span class="gp">>>> </span><span class="n">m</span><span class="o">.</span><span class="n">hexdigest</span><span class="p">()</span>
|
||
<span class="go">'900150983cd24fb0d6963f7d28e17f72'</span>
|
||
<span class="gp">>>> </span><span class="n">MD5</span><span class="o">.</span><span class="n">new</span><span class="p">(</span><span class="sa">b</span><span class="s1">'abc'</span><span class="p">)</span><span class="o">.</span><span class="n">digest</span><span class="p">()</span>
|
||
<span class="go">b'\x90\x01P\x98<\xd2O\xb0\xd6\x96?}(\xe1\x7fr'</span>
|
||
</pre></div>
|
||
</div>
|
||
</section>
|
||
<section id="rationale">
|
||
<h2><a class="toc-backref" href="#rationale" role="doc-backlink">Rationale</a></h2>
|
||
<p>The digest size is measured in bytes, not bits, even though hash
|
||
algorithm sizes are usually quoted in bits; MD5 is a 128-bit
|
||
algorithm and not a 16-byte one, for example. This is because, in
|
||
the sample code I looked at, the length in bytes is often needed
|
||
(to seek ahead or behind in a file; to compute the length of an
|
||
output string) while the length in bits is rarely used.
|
||
Therefore, the burden will fall on the few people actually needing
|
||
the size in bits, who will have to multiply digest_size by 8.</p>
|
||
<p>It’s been suggested that the <code class="docutils literal notranslate"><span class="pre">update()</span></code> method would be better named
|
||
<code class="docutils literal notranslate"><span class="pre">append()</span></code>. However, that method is really causing the current
|
||
state of the hashing object to be updated, and <code class="docutils literal notranslate"><span class="pre">update()</span></code> is already
|
||
used by the md5 and sha modules included with Python, so it seems
|
||
simplest to leave the name <code class="docutils literal notranslate"><span class="pre">update()</span></code> alone.</p>
|
||
<p>The order of the constructor’s arguments for keyed hashes was a
|
||
sticky issue. It wasn’t clear whether the key should come first
|
||
or second. It’s a required parameter, and the usual convention is
|
||
to place required parameters first, but that also means that the
|
||
‘string’ parameter moves from the first position to the second.
|
||
It would be possible to get confused and pass a single argument to
|
||
a keyed hash, thinking that you’re passing an initial string to an
|
||
unkeyed hash, but it doesn’t seem worth making the interface
|
||
for keyed hashes more obscure to avoid this potential error.</p>
|
||
</section>
|
||
<section id="changes-from-version-1-0-to-version-2-0">
|
||
<h2><a class="toc-backref" href="#changes-from-version-1-0-to-version-2-0" role="doc-backlink">Changes from Version 1.0 to Version 2.0</a></h2>
|
||
<p>Version 2.0 of API for Cryptographic Hash Functions clarifies some
|
||
aspects of the API and brings it up-to-date. It also formalized aspects
|
||
that were already de facto standards and provided by most
|
||
implementations.</p>
|
||
<p>Version 2.0 introduces the following new attributes:</p>
|
||
<dl class="simple">
|
||
<dt><code class="docutils literal notranslate"><span class="pre">name</span></code></dt><dd>The name property was made mandatory by <a class="reference external" href="http://bugs.python.org/issue18532">issue 18532</a>.</dd>
|
||
<dt><code class="docutils literal notranslate"><span class="pre">block_size</span></code></dt><dd>The new version also specifies that the return value
|
||
<code class="docutils literal notranslate"><span class="pre">NotImplemented</span></code> prevents HMAC support.</dd>
|
||
</dl>
|
||
<p>Version 2.0 takes the separation of binary and text data in Python
|
||
3.0 into account. The ‘string’ argument to <code class="docutils literal notranslate"><span class="pre">new()</span></code> and <code class="docutils literal notranslate"><span class="pre">update()</span></code> as
|
||
well as the ‘key’ argument must be bytes-like objects. On Python
|
||
2.x a hashing object may also support ASCII-only unicode. The actual
|
||
name of argument is not changed as it is part of the public API.
|
||
Code may depend on the fact that the argument is called ‘string’.</p>
|
||
</section>
|
||
<section id="recommended-names-for-common-hashing-algorithms">
|
||
<h2><a class="toc-backref" href="#recommended-names-for-common-hashing-algorithms" role="doc-backlink">Recommended names for common hashing algorithms</a></h2>
|
||
<table class="docutils align-default">
|
||
<thead>
|
||
<tr class="row-odd"><th class="head">algorithm</th>
|
||
<th class="head">variant</th>
|
||
<th class="head">recommended name</th>
|
||
</tr>
|
||
</thead>
|
||
<tbody>
|
||
<tr class="row-even"><td>MD5</td>
|
||
<td></td>
|
||
<td>md5</td>
|
||
</tr>
|
||
<tr class="row-odd"><td>RIPEMD-160</td>
|
||
<td></td>
|
||
<td>ripemd160</td>
|
||
</tr>
|
||
<tr class="row-even"><td>SHA-1</td>
|
||
<td></td>
|
||
<td>sha1</td>
|
||
</tr>
|
||
<tr class="row-odd"><td rowspan="4">SHA-2</td>
|
||
<td>SHA-224</td>
|
||
<td>sha224</td>
|
||
</tr>
|
||
<tr class="row-even"><td>SHA-256</td>
|
||
<td>sha256</td>
|
||
</tr>
|
||
<tr class="row-odd"><td>SHA-384</td>
|
||
<td>sha384</td>
|
||
</tr>
|
||
<tr class="row-even"><td>SHA-512</td>
|
||
<td>sha512</td>
|
||
</tr>
|
||
<tr class="row-odd"><td rowspan="4">SHA-3</td>
|
||
<td>SHA-3-224</td>
|
||
<td>sha3_224</td>
|
||
</tr>
|
||
<tr class="row-even"><td>SHA-3-256</td>
|
||
<td>sha3_256</td>
|
||
</tr>
|
||
<tr class="row-odd"><td>SHA-3-384</td>
|
||
<td>sha3_384</td>
|
||
</tr>
|
||
<tr class="row-even"><td>SHA-3-512</td>
|
||
<td>sha3_512</td>
|
||
</tr>
|
||
<tr class="row-odd"><td>WHIRLPOOL</td>
|
||
<td></td>
|
||
<td>whirlpool</td>
|
||
</tr>
|
||
</tbody>
|
||
</table>
|
||
</section>
|
||
<section id="changes">
|
||
<h2><a class="toc-backref" href="#changes" role="doc-backlink">Changes</a></h2>
|
||
<ul class="simple">
|
||
<li>2001-09-17: Renamed <code class="docutils literal notranslate"><span class="pre">clear()</span></code> to <code class="docutils literal notranslate"><span class="pre">reset()</span></code>; added <code class="docutils literal notranslate"><span class="pre">digest_size</span></code> attribute
|
||
to objects; added <code class="docutils literal notranslate"><span class="pre">.hexdigest()</span></code> method.</li>
|
||
<li>2001-09-20: Removed <code class="docutils literal notranslate"><span class="pre">reset()</span></code> method completely.</li>
|
||
<li>2001-09-28: Set <code class="docutils literal notranslate"><span class="pre">digest_size</span></code> to <code class="docutils literal notranslate"><span class="pre">None</span></code> for variable-size hashes.</li>
|
||
<li>2013-08-15: Added <code class="docutils literal notranslate"><span class="pre">block_size</span></code> and <code class="docutils literal notranslate"><span class="pre">name</span></code> attributes; clarified that
|
||
‘string’ actually refers to bytes-like objects.</li>
|
||
</ul>
|
||
</section>
|
||
<section id="acknowledgements">
|
||
<h2><a class="toc-backref" href="#acknowledgements" role="doc-backlink">Acknowledgements</a></h2>
|
||
<p>Thanks to Aahz, Andrew Archibald, Rich Salz, Itamar
|
||
Shtull-Trauring, and the readers of the python-crypto list for
|
||
their comments on this PEP.</p>
|
||
</section>
|
||
<section id="copyright">
|
||
<h2><a class="toc-backref" href="#copyright" role="doc-backlink">Copyright</a></h2>
|
||
<p>This document has been placed in the public domain.</p>
|
||
</section>
|
||
</section>
|
||
<hr class="docutils" />
|
||
<p>Source: <a class="reference external" href="https://github.com/python/peps/blob/main/peps/pep-0452.rst">https://github.com/python/peps/blob/main/peps/pep-0452.rst</a></p>
|
||
<p>Last modified: <a class="reference external" href="https://github.com/python/peps/commits/main/peps/pep-0452.rst">2023-09-09 17:39:29 GMT</a></p>
|
||
|
||
</article>
|
||
<nav id="pep-sidebar">
|
||
<h2>Contents</h2>
|
||
<ul>
|
||
<li><a class="reference internal" href="#abstract">Abstract</a></li>
|
||
<li><a class="reference internal" href="#specification">Specification</a></li>
|
||
<li><a class="reference internal" href="#rationale">Rationale</a></li>
|
||
<li><a class="reference internal" href="#changes-from-version-1-0-to-version-2-0">Changes from Version 1.0 to Version 2.0</a></li>
|
||
<li><a class="reference internal" href="#recommended-names-for-common-hashing-algorithms">Recommended names for common hashing algorithms</a></li>
|
||
<li><a class="reference internal" href="#changes">Changes</a></li>
|
||
<li><a class="reference internal" href="#acknowledgements">Acknowledgements</a></li>
|
||
<li><a class="reference internal" href="#copyright">Copyright</a></li>
|
||
</ul>
|
||
|
||
<br>
|
||
<a id="source" href="https://github.com/python/peps/blob/main/peps/pep-0452.rst">Page Source (GitHub)</a>
|
||
</nav>
|
||
</section>
|
||
<script src="../_static/colour_scheme.js"></script>
|
||
<script src="../_static/wrap_tables.js"></script>
|
||
<script src="../_static/sticky_banner.js"></script>
|
||
</body>
|
||
</html> |