2
0
mirror of https://github.com/boostorg/hash2.git synced 2026-02-01 20:42:13 +00:00
Files
hash2/doc/html/hash2.html
2024-11-16 02:46:16 +02:00

4520 lines
281 KiB
HTML

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="generator" content="Asciidoctor 2.0.18">
<meta name="author" content="Peter Dimov">
<title>Hash2: An Extensible Hashing Framework</title>
<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Open+Sans:300,300italic,400,400italic,600,600italic%7CNoto+Serif:400,400italic,700,700italic%7CDroid+Sans+Mono:400,700">
<style>
/*! Asciidoctor default stylesheet | MIT License | https://asciidoctor.org */
/* Uncomment the following line when using as a custom stylesheet */
/* @import "https://fonts.googleapis.com/css?family=Open+Sans:300,300italic,400,400italic,600,600italic%7CNoto+Serif:400,400italic,700,700italic%7CDroid+Sans+Mono:400,700"; */
html{font-family:sans-serif;-webkit-text-size-adjust:100%}
a{background:none}
a:focus{outline:thin dotted}
a:active,a:hover{outline:0}
h1{font-size:2em;margin:.67em 0}
b,strong{font-weight:bold}
abbr{font-size:.9em}
abbr[title]{cursor:help;border-bottom:1px dotted #dddddf;text-decoration:none}
dfn{font-style:italic}
hr{height:0}
mark{background:#ff0;color:#000}
code,kbd,pre,samp{font-family:monospace;font-size:1em}
pre{white-space:pre-wrap}
q{quotes:"\201C" "\201D" "\2018" "\2019"}
small{font-size:80%}
sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}
sup{top:-.5em}
sub{bottom:-.25em}
img{border:0}
svg:not(:root){overflow:hidden}
figure{margin:0}
audio,video{display:inline-block}
audio:not([controls]){display:none;height:0}
fieldset{border:1px solid silver;margin:0 2px;padding:.35em .625em .75em}
legend{border:0;padding:0}
button,input,select,textarea{font-family:inherit;font-size:100%;margin:0}
button,input{line-height:normal}
button,select{text-transform:none}
button,html input[type=button],input[type=reset],input[type=submit]{-webkit-appearance:button;cursor:pointer}
button[disabled],html input[disabled]{cursor:default}
input[type=checkbox],input[type=radio]{padding:0}
button::-moz-focus-inner,input::-moz-focus-inner{border:0;padding:0}
textarea{overflow:auto;vertical-align:top}
table{border-collapse:collapse;border-spacing:0}
*,::before,::after{box-sizing:border-box}
html,body{font-size:100%}
body{background:#fff;color:rgba(0,0,0,.8);padding:0;margin:0;font-family:"Noto Serif","DejaVu Serif",serif;line-height:1;position:relative;cursor:auto;-moz-tab-size:4;-o-tab-size:4;tab-size:4;word-wrap:anywhere;-moz-osx-font-smoothing:grayscale;-webkit-font-smoothing:antialiased}
a:hover{cursor:pointer}
img,object,embed{max-width:100%;height:auto}
object,embed{height:100%}
img{-ms-interpolation-mode:bicubic}
.left{float:left!important}
.right{float:right!important}
.text-left{text-align:left!important}
.text-right{text-align:right!important}
.text-center{text-align:center!important}
.text-justify{text-align:justify!important}
.hide{display:none}
img,object,svg{display:inline-block;vertical-align:middle}
textarea{height:auto;min-height:50px}
select{width:100%}
.subheader,.admonitionblock td.content>.title,.audioblock>.title,.exampleblock>.title,.imageblock>.title,.listingblock>.title,.literalblock>.title,.stemblock>.title,.openblock>.title,.paragraph>.title,.quoteblock>.title,table.tableblock>.title,.verseblock>.title,.videoblock>.title,.dlist>.title,.olist>.title,.ulist>.title,.qlist>.title,.hdlist>.title{line-height:1.45;color:#7a2518;font-weight:400;margin-top:0;margin-bottom:.25em}
div,dl,dt,dd,ul,ol,li,h1,h2,h3,#toctitle,.sidebarblock>.content>.title,h4,h5,h6,pre,form,p,blockquote,th,td{margin:0;padding:0}
a{color:#2156a5;text-decoration:underline;line-height:inherit}
a:hover,a:focus{color:#1d4b8f}
a img{border:0}
p{line-height:1.6;margin-bottom:1.25em;text-rendering:optimizeLegibility}
p aside{font-size:.875em;line-height:1.35;font-style:italic}
h1,h2,h3,#toctitle,.sidebarblock>.content>.title,h4,h5,h6{font-family:"Open Sans","DejaVu Sans",sans-serif;font-weight:300;font-style:normal;color:#ba3925;text-rendering:optimizeLegibility;margin-top:1em;margin-bottom:.5em;line-height:1.0125em}
h1 small,h2 small,h3 small,#toctitle small,.sidebarblock>.content>.title small,h4 small,h5 small,h6 small{font-size:60%;color:#e99b8f;line-height:0}
h1{font-size:2.125em}
h2{font-size:1.6875em}
h3,#toctitle,.sidebarblock>.content>.title{font-size:1.375em}
h4,h5{font-size:1.125em}
h6{font-size:1em}
hr{border:solid #dddddf;border-width:1px 0 0;clear:both;margin:1.25em 0 1.1875em}
em,i{font-style:italic;line-height:inherit}
strong,b{font-weight:bold;line-height:inherit}
small{font-size:60%;line-height:inherit}
code{font-family:"Droid Sans Mono","DejaVu Sans Mono",monospace;font-weight:400;color:rgba(0,0,0,.9)}
ul,ol,dl{line-height:1.6;margin-bottom:1.25em;list-style-position:outside;font-family:inherit}
ul,ol{margin-left:1.5em}
ul li ul,ul li ol{margin-left:1.25em;margin-bottom:0}
ul.circle{list-style-type:circle}
ul.disc{list-style-type:disc}
ul.square{list-style-type:square}
ul.circle ul:not([class]),ul.disc ul:not([class]),ul.square ul:not([class]){list-style:inherit}
ol li ul,ol li ol{margin-left:1.25em;margin-bottom:0}
dl dt{margin-bottom:.3125em;font-weight:bold}
dl dd{margin-bottom:1.25em}
blockquote{margin:0 0 1.25em;padding:.5625em 1.25em 0 1.1875em;border-left:1px solid #ddd}
blockquote,blockquote p{line-height:1.6;color:rgba(0,0,0,.85)}
@media screen and (min-width:768px){h1,h2,h3,#toctitle,.sidebarblock>.content>.title,h4,h5,h6{line-height:1.2}
h1{font-size:2.75em}
h2{font-size:2.3125em}
h3,#toctitle,.sidebarblock>.content>.title{font-size:1.6875em}
h4{font-size:1.4375em}}
table{background:#fff;margin-bottom:1.25em;border:1px solid #dedede;word-wrap:normal}
table thead,table tfoot{background:#f7f8f7}
table thead tr th,table thead tr td,table tfoot tr th,table tfoot tr td{padding:.5em .625em .625em;font-size:inherit;color:rgba(0,0,0,.8);text-align:left}
table tr th,table tr td{padding:.5625em .625em;font-size:inherit;color:rgba(0,0,0,.8)}
table tr.even,table tr.alt{background:#f8f8f7}
table thead tr th,table tfoot tr th,table tbody tr td,table tr td,table tfoot tr td{line-height:1.6}
h1,h2,h3,#toctitle,.sidebarblock>.content>.title,h4,h5,h6{line-height:1.2;word-spacing:-.05em}
h1 strong,h2 strong,h3 strong,#toctitle strong,.sidebarblock>.content>.title strong,h4 strong,h5 strong,h6 strong{font-weight:400}
.center{margin-left:auto;margin-right:auto}
.stretch{width:100%}
.clearfix::before,.clearfix::after,.float-group::before,.float-group::after{content:" ";display:table}
.clearfix::after,.float-group::after{clear:both}
:not(pre).nobreak{word-wrap:normal}
:not(pre).nowrap{white-space:nowrap}
:not(pre).pre-wrap{white-space:pre-wrap}
:not(pre):not([class^=L])>code{font-size:.9375em;font-style:normal!important;letter-spacing:0;padding:.1em .5ex;word-spacing:-.15em;background:#f7f7f8;border-radius:4px;line-height:1.45;text-rendering:optimizeSpeed}
pre{color:rgba(0,0,0,.9);font-family:"Droid Sans Mono","DejaVu Sans Mono",monospace;line-height:1.45;text-rendering:optimizeSpeed}
pre code,pre pre{color:inherit;font-size:inherit;line-height:inherit}
pre>code{display:block}
pre.nowrap,pre.nowrap pre{white-space:pre;word-wrap:normal}
em em{font-style:normal}
strong strong{font-weight:400}
.keyseq{color:rgba(51,51,51,.8)}
kbd{font-family:"Droid Sans Mono","DejaVu Sans Mono",monospace;display:inline-block;color:rgba(0,0,0,.8);font-size:.65em;line-height:1.45;background:#f7f7f7;border:1px solid #ccc;border-radius:3px;box-shadow:0 1px 0 rgba(0,0,0,.2),inset 0 0 0 .1em #fff;margin:0 .15em;padding:.2em .5em;vertical-align:middle;position:relative;top:-.1em;white-space:nowrap}
.keyseq kbd:first-child{margin-left:0}
.keyseq kbd:last-child{margin-right:0}
.menuseq,.menuref{color:#000}
.menuseq b:not(.caret),.menuref{font-weight:inherit}
.menuseq{word-spacing:-.02em}
.menuseq b.caret{font-size:1.25em;line-height:.8}
.menuseq i.caret{font-weight:bold;text-align:center;width:.45em}
b.button::before,b.button::after{position:relative;top:-1px;font-weight:400}
b.button::before{content:"[";padding:0 3px 0 2px}
b.button::after{content:"]";padding:0 2px 0 3px}
p a>code:hover{color:rgba(0,0,0,.9)}
#header,#content,#footnotes,#footer{width:100%;margin:0 auto;max-width:62.5em;*zoom:1;position:relative;padding-left:.9375em;padding-right:.9375em}
#header::before,#header::after,#content::before,#content::after,#footnotes::before,#footnotes::after,#footer::before,#footer::after{content:" ";display:table}
#header::after,#content::after,#footnotes::after,#footer::after{clear:both}
#content{margin-top:1.25em}
#content::before{content:none}
#header>h1:first-child{color:rgba(0,0,0,.85);margin-top:2.25rem;margin-bottom:0}
#header>h1:first-child+#toc{margin-top:8px;border-top:1px solid #dddddf}
#header>h1:only-child,body.toc2 #header>h1:nth-last-child(2){border-bottom:1px solid #dddddf;padding-bottom:8px}
#header .details{border-bottom:1px solid #dddddf;line-height:1.45;padding-top:.25em;padding-bottom:.25em;padding-left:.25em;color:rgba(0,0,0,.6);display:flex;flex-flow:row wrap}
#header .details span:first-child{margin-left:-.125em}
#header .details span.email a{color:rgba(0,0,0,.85)}
#header .details br{display:none}
#header .details br+span::before{content:"\00a0\2013\00a0"}
#header .details br+span.author::before{content:"\00a0\22c5\00a0";color:rgba(0,0,0,.85)}
#header .details br+span#revremark::before{content:"\00a0|\00a0"}
#header #revnumber{text-transform:capitalize}
#header #revnumber::after{content:"\00a0"}
#content>h1:first-child:not([class]){color:rgba(0,0,0,.85);border-bottom:1px solid #dddddf;padding-bottom:8px;margin-top:0;padding-top:1rem;margin-bottom:1.25rem}
#toc{border-bottom:1px solid #e7e7e9;padding-bottom:.5em}
#toc>ul{margin-left:.125em}
#toc ul.sectlevel0>li>a{font-style:italic}
#toc ul.sectlevel0 ul.sectlevel1{margin:.5em 0}
#toc ul{font-family:"Open Sans","DejaVu Sans",sans-serif;list-style-type:none}
#toc li{line-height:1.3334;margin-top:.3334em}
#toc a{text-decoration:none}
#toc a:active{text-decoration:underline}
#toctitle{color:#7a2518;font-size:1.2em}
@media screen and (min-width:768px){#toctitle{font-size:1.375em}
body.toc2{padding-left:15em;padding-right:0}
#toc.toc2{margin-top:0!important;background:#f8f8f7;position:fixed;width:15em;left:0;top:0;border-right:1px solid #e7e7e9;border-top-width:0!important;border-bottom-width:0!important;z-index:1000;padding:1.25em 1em;height:100%;overflow:auto}
#toc.toc2 #toctitle{margin-top:0;margin-bottom:.8rem;font-size:1.2em}
#toc.toc2>ul{font-size:.9em;margin-bottom:0}
#toc.toc2 ul ul{margin-left:0;padding-left:1em}
#toc.toc2 ul.sectlevel0 ul.sectlevel1{padding-left:0;margin-top:.5em;margin-bottom:.5em}
body.toc2.toc-right{padding-left:0;padding-right:15em}
body.toc2.toc-right #toc.toc2{border-right-width:0;border-left:1px solid #e7e7e9;left:auto;right:0}}
@media screen and (min-width:1280px){body.toc2{padding-left:20em;padding-right:0}
#toc.toc2{width:20em}
#toc.toc2 #toctitle{font-size:1.375em}
#toc.toc2>ul{font-size:.95em}
#toc.toc2 ul ul{padding-left:1.25em}
body.toc2.toc-right{padding-left:0;padding-right:20em}}
#content #toc{border:1px solid #e0e0dc;margin-bottom:1.25em;padding:1.25em;background:#f8f8f7;border-radius:4px}
#content #toc>:first-child{margin-top:0}
#content #toc>:last-child{margin-bottom:0}
#footer{max-width:none;background:rgba(0,0,0,.8);padding:1.25em}
#footer-text{color:hsla(0,0%,100%,.8);line-height:1.44}
#content{margin-bottom:.625em}
.sect1{padding-bottom:.625em}
@media screen and (min-width:768px){#content{margin-bottom:1.25em}
.sect1{padding-bottom:1.25em}}
.sect1:last-child{padding-bottom:0}
.sect1+.sect1{border-top:1px solid #e7e7e9}
#content h1>a.anchor,h2>a.anchor,h3>a.anchor,#toctitle>a.anchor,.sidebarblock>.content>.title>a.anchor,h4>a.anchor,h5>a.anchor,h6>a.anchor{position:absolute;z-index:1001;width:1.5ex;margin-left:-1.5ex;display:block;text-decoration:none!important;visibility:hidden;text-align:center;font-weight:400}
#content h1>a.anchor::before,h2>a.anchor::before,h3>a.anchor::before,#toctitle>a.anchor::before,.sidebarblock>.content>.title>a.anchor::before,h4>a.anchor::before,h5>a.anchor::before,h6>a.anchor::before{content:"\00A7";font-size:.85em;display:block;padding-top:.1em}
#content h1:hover>a.anchor,#content h1>a.anchor:hover,h2:hover>a.anchor,h2>a.anchor:hover,h3:hover>a.anchor,#toctitle:hover>a.anchor,.sidebarblock>.content>.title:hover>a.anchor,h3>a.anchor:hover,#toctitle>a.anchor:hover,.sidebarblock>.content>.title>a.anchor:hover,h4:hover>a.anchor,h4>a.anchor:hover,h5:hover>a.anchor,h5>a.anchor:hover,h6:hover>a.anchor,h6>a.anchor:hover{visibility:visible}
#content h1>a.link,h2>a.link,h3>a.link,#toctitle>a.link,.sidebarblock>.content>.title>a.link,h4>a.link,h5>a.link,h6>a.link{color:#ba3925;text-decoration:none}
#content h1>a.link:hover,h2>a.link:hover,h3>a.link:hover,#toctitle>a.link:hover,.sidebarblock>.content>.title>a.link:hover,h4>a.link:hover,h5>a.link:hover,h6>a.link:hover{color:#a53221}
details,.audioblock,.imageblock,.literalblock,.listingblock,.stemblock,.videoblock{margin-bottom:1.25em}
details{margin-left:1.25rem}
details>summary{cursor:pointer;display:block;position:relative;line-height:1.6;margin-bottom:.625rem;outline:none;-webkit-tap-highlight-color:transparent}
details>summary::-webkit-details-marker{display:none}
details>summary::before{content:"";border:solid transparent;border-left:solid;border-width:.3em 0 .3em .5em;position:absolute;top:.5em;left:-1.25rem;transform:translateX(15%)}
details[open]>summary::before{border:solid transparent;border-top:solid;border-width:.5em .3em 0;transform:translateY(15%)}
details>summary::after{content:"";width:1.25rem;height:1em;position:absolute;top:.3em;left:-1.25rem}
.admonitionblock td.content>.title,.audioblock>.title,.exampleblock>.title,.imageblock>.title,.listingblock>.title,.literalblock>.title,.stemblock>.title,.openblock>.title,.paragraph>.title,.quoteblock>.title,table.tableblock>.title,.verseblock>.title,.videoblock>.title,.dlist>.title,.olist>.title,.ulist>.title,.qlist>.title,.hdlist>.title{text-rendering:optimizeLegibility;text-align:left;font-family:"Noto Serif","DejaVu Serif",serif;font-size:1rem;font-style:italic}
table.tableblock.fit-content>caption.title{white-space:nowrap;width:0}
.paragraph.lead>p,#preamble>.sectionbody>[class=paragraph]:first-of-type p{font-size:1.21875em;line-height:1.6;color:rgba(0,0,0,.85)}
.admonitionblock>table{border-collapse:separate;border:0;background:none;width:100%}
.admonitionblock>table td.icon{text-align:center;width:80px}
.admonitionblock>table td.icon img{max-width:none}
.admonitionblock>table td.icon .title{font-weight:bold;font-family:"Open Sans","DejaVu Sans",sans-serif;text-transform:uppercase}
.admonitionblock>table td.content{padding-left:1.125em;padding-right:1.25em;border-left:1px solid #dddddf;color:rgba(0,0,0,.6);word-wrap:anywhere}
.admonitionblock>table td.content>:last-child>:last-child{margin-bottom:0}
.exampleblock>.content{border:1px solid #e6e6e6;margin-bottom:1.25em;padding:1.25em;background:#fff;border-radius:4px}
.exampleblock>.content>:first-child{margin-top:0}
.exampleblock>.content>:last-child{margin-bottom:0}
.sidebarblock{border:1px solid #dbdbd6;margin-bottom:1.25em;padding:1.25em;background:#f3f3f2;border-radius:4px}
.sidebarblock>:first-child{margin-top:0}
.sidebarblock>:last-child{margin-bottom:0}
.sidebarblock>.content>.title{color:#7a2518;margin-top:0;text-align:center}
.exampleblock>.content>:last-child>:last-child,.exampleblock>.content .olist>ol>li:last-child>:last-child,.exampleblock>.content .ulist>ul>li:last-child>:last-child,.exampleblock>.content .qlist>ol>li:last-child>:last-child,.sidebarblock>.content>:last-child>:last-child,.sidebarblock>.content .olist>ol>li:last-child>:last-child,.sidebarblock>.content .ulist>ul>li:last-child>:last-child,.sidebarblock>.content .qlist>ol>li:last-child>:last-child{margin-bottom:0}
.literalblock pre,.listingblock>.content>pre{border-radius:4px;overflow-x:auto;padding:1em;font-size:.8125em}
@media screen and (min-width:768px){.literalblock pre,.listingblock>.content>pre{font-size:.90625em}}
@media screen and (min-width:1280px){.literalblock pre,.listingblock>.content>pre{font-size:1em}}
.literalblock pre,.listingblock>.content>pre:not(.highlight),.listingblock>.content>pre[class=highlight],.listingblock>.content>pre[class^="highlight "]{background:#f7f7f8}
.literalblock.output pre{color:#f7f7f8;background:rgba(0,0,0,.9)}
.listingblock>.content{position:relative}
.listingblock code[data-lang]::before{display:none;content:attr(data-lang);position:absolute;font-size:.75em;top:.425rem;right:.5rem;line-height:1;text-transform:uppercase;color:inherit;opacity:.5}
.listingblock:hover code[data-lang]::before{display:block}
.listingblock.terminal pre .command::before{content:attr(data-prompt);padding-right:.5em;color:inherit;opacity:.5}
.listingblock.terminal pre .command:not([data-prompt])::before{content:"$"}
.listingblock pre.highlightjs{padding:0}
.listingblock pre.highlightjs>code{padding:1em;border-radius:4px}
.listingblock pre.prettyprint{border-width:0}
.prettyprint{background:#f7f7f8}
pre.prettyprint .linenums{line-height:1.45;margin-left:2em}
pre.prettyprint li{background:none;list-style-type:inherit;padding-left:0}
pre.prettyprint li code[data-lang]::before{opacity:1}
pre.prettyprint li:not(:first-child) code[data-lang]::before{display:none}
table.linenotable{border-collapse:separate;border:0;margin-bottom:0;background:none}
table.linenotable td[class]{color:inherit;vertical-align:top;padding:0;line-height:inherit;white-space:normal}
table.linenotable td.code{padding-left:.75em}
table.linenotable td.linenos,pre.pygments .linenos{border-right:1px solid;opacity:.35;padding-right:.5em;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}
pre.pygments span.linenos{display:inline-block;margin-right:.75em}
.quoteblock{margin:0 1em 1.25em 1.5em;display:table}
.quoteblock:not(.excerpt)>.title{margin-left:-1.5em;margin-bottom:.75em}
.quoteblock blockquote,.quoteblock p{color:rgba(0,0,0,.85);font-size:1.15rem;line-height:1.75;word-spacing:.1em;letter-spacing:0;font-style:italic;text-align:justify}
.quoteblock blockquote{margin:0;padding:0;border:0}
.quoteblock blockquote::before{content:"\201c";float:left;font-size:2.75em;font-weight:bold;line-height:.6em;margin-left:-.6em;color:#7a2518;text-shadow:0 1px 2px rgba(0,0,0,.1)}
.quoteblock blockquote>.paragraph:last-child p{margin-bottom:0}
.quoteblock .attribution{margin-top:.75em;margin-right:.5ex;text-align:right}
.verseblock{margin:0 1em 1.25em}
.verseblock pre{font-family:"Open Sans","DejaVu Sans",sans-serif;font-size:1.15rem;color:rgba(0,0,0,.85);font-weight:300;text-rendering:optimizeLegibility}
.verseblock pre strong{font-weight:400}
.verseblock .attribution{margin-top:1.25rem;margin-left:.5ex}
.quoteblock .attribution,.verseblock .attribution{font-size:.9375em;line-height:1.45;font-style:italic}
.quoteblock .attribution br,.verseblock .attribution br{display:none}
.quoteblock .attribution cite,.verseblock .attribution cite{display:block;letter-spacing:-.025em;color:rgba(0,0,0,.6)}
.quoteblock.abstract blockquote::before,.quoteblock.excerpt blockquote::before,.quoteblock .quoteblock blockquote::before{display:none}
.quoteblock.abstract blockquote,.quoteblock.abstract p,.quoteblock.excerpt blockquote,.quoteblock.excerpt p,.quoteblock .quoteblock blockquote,.quoteblock .quoteblock p{line-height:1.6;word-spacing:0}
.quoteblock.abstract{margin:0 1em 1.25em;display:block}
.quoteblock.abstract>.title{margin:0 0 .375em;font-size:1.15em;text-align:center}
.quoteblock.excerpt>blockquote,.quoteblock .quoteblock{padding:0 0 .25em 1em;border-left:.25em solid #dddddf}
.quoteblock.excerpt,.quoteblock .quoteblock{margin-left:0}
.quoteblock.excerpt blockquote,.quoteblock.excerpt p,.quoteblock .quoteblock blockquote,.quoteblock .quoteblock p{color:inherit;font-size:1.0625rem}
.quoteblock.excerpt .attribution,.quoteblock .quoteblock .attribution{color:inherit;font-size:.85rem;text-align:left;margin-right:0}
p.tableblock:last-child{margin-bottom:0}
td.tableblock>.content{margin-bottom:1.25em;word-wrap:anywhere}
td.tableblock>.content>:last-child{margin-bottom:-1.25em}
table.tableblock,th.tableblock,td.tableblock{border:0 solid #dedede}
table.grid-all>*>tr>*{border-width:1px}
table.grid-cols>*>tr>*{border-width:0 1px}
table.grid-rows>*>tr>*{border-width:1px 0}
table.frame-all{border-width:1px}
table.frame-ends{border-width:1px 0}
table.frame-sides{border-width:0 1px}
table.frame-none>colgroup+*>:first-child>*,table.frame-sides>colgroup+*>:first-child>*{border-top-width:0}
table.frame-none>:last-child>:last-child>*,table.frame-sides>:last-child>:last-child>*{border-bottom-width:0}
table.frame-none>*>tr>:first-child,table.frame-ends>*>tr>:first-child{border-left-width:0}
table.frame-none>*>tr>:last-child,table.frame-ends>*>tr>:last-child{border-right-width:0}
table.stripes-all>*>tr,table.stripes-odd>*>tr:nth-of-type(odd),table.stripes-even>*>tr:nth-of-type(even),table.stripes-hover>*>tr:hover{background:#f8f8f7}
th.halign-left,td.halign-left{text-align:left}
th.halign-right,td.halign-right{text-align:right}
th.halign-center,td.halign-center{text-align:center}
th.valign-top,td.valign-top{vertical-align:top}
th.valign-bottom,td.valign-bottom{vertical-align:bottom}
th.valign-middle,td.valign-middle{vertical-align:middle}
table thead th,table tfoot th{font-weight:bold}
tbody tr th{background:#f7f8f7}
tbody tr th,tbody tr th p,tfoot tr th,tfoot tr th p{color:rgba(0,0,0,.8);font-weight:bold}
p.tableblock>code:only-child{background:none;padding:0}
p.tableblock{font-size:1em}
ol{margin-left:1.75em}
ul li ol{margin-left:1.5em}
dl dd{margin-left:1.125em}
dl dd:last-child,dl dd:last-child>:last-child{margin-bottom:0}
li p,ul dd,ol dd,.olist .olist,.ulist .ulist,.ulist .olist,.olist .ulist{margin-bottom:.625em}
ul.checklist,ul.none,ol.none,ul.no-bullet,ol.no-bullet,ol.unnumbered,ul.unstyled,ol.unstyled{list-style-type:none}
ul.no-bullet,ol.no-bullet,ol.unnumbered{margin-left:.625em}
ul.unstyled,ol.unstyled{margin-left:0}
li>p:empty:only-child::before{content:"";display:inline-block}
ul.checklist>li>p:first-child{margin-left:-1em}
ul.checklist>li>p:first-child>.fa-square-o:first-child,ul.checklist>li>p:first-child>.fa-check-square-o:first-child{width:1.25em;font-size:.8em;position:relative;bottom:.125em}
ul.checklist>li>p:first-child>input[type=checkbox]:first-child{margin-right:.25em}
ul.inline{display:flex;flex-flow:row wrap;list-style:none;margin:0 0 .625em -1.25em}
ul.inline>li{margin-left:1.25em}
.unstyled dl dt{font-weight:400;font-style:normal}
ol.arabic{list-style-type:decimal}
ol.decimal{list-style-type:decimal-leading-zero}
ol.loweralpha{list-style-type:lower-alpha}
ol.upperalpha{list-style-type:upper-alpha}
ol.lowerroman{list-style-type:lower-roman}
ol.upperroman{list-style-type:upper-roman}
ol.lowergreek{list-style-type:lower-greek}
.hdlist>table,.colist>table{border:0;background:none}
.hdlist>table>tbody>tr,.colist>table>tbody>tr{background:none}
td.hdlist1,td.hdlist2{vertical-align:top;padding:0 .625em}
td.hdlist1{font-weight:bold;padding-bottom:1.25em}
td.hdlist2{word-wrap:anywhere}
.literalblock+.colist,.listingblock+.colist{margin-top:-.5em}
.colist td:not([class]):first-child{padding:.4em .75em 0;line-height:1;vertical-align:top}
.colist td:not([class]):first-child img{max-width:none}
.colist td:not([class]):last-child{padding:.25em 0}
.thumb,.th{line-height:0;display:inline-block;border:4px solid #fff;box-shadow:0 0 0 1px #ddd}
.imageblock.left{margin:.25em .625em 1.25em 0}
.imageblock.right{margin:.25em 0 1.25em .625em}
.imageblock>.title{margin-bottom:0}
.imageblock.thumb,.imageblock.th{border-width:6px}
.imageblock.thumb>.title,.imageblock.th>.title{padding:0 .125em}
.image.left,.image.right{margin-top:.25em;margin-bottom:.25em;display:inline-block;line-height:0}
.image.left{margin-right:.625em}
.image.right{margin-left:.625em}
a.image{text-decoration:none;display:inline-block}
a.image object{pointer-events:none}
sup.footnote,sup.footnoteref{font-size:.875em;position:static;vertical-align:super}
sup.footnote a,sup.footnoteref a{text-decoration:none}
sup.footnote a:active,sup.footnoteref a:active{text-decoration:underline}
#footnotes{padding-top:.75em;padding-bottom:.75em;margin-bottom:.625em}
#footnotes hr{width:20%;min-width:6.25em;margin:-.25em 0 .75em;border-width:1px 0 0}
#footnotes .footnote{padding:0 .375em 0 .225em;line-height:1.3334;font-size:.875em;margin-left:1.2em;margin-bottom:.2em}
#footnotes .footnote a:first-of-type{font-weight:bold;text-decoration:none;margin-left:-1.05em}
#footnotes .footnote:last-of-type{margin-bottom:0}
#content #footnotes{margin-top:-.625em;margin-bottom:0;padding:.75em 0}
div.unbreakable{page-break-inside:avoid}
.big{font-size:larger}
.small{font-size:smaller}
.underline{text-decoration:underline}
.overline{text-decoration:overline}
.line-through{text-decoration:line-through}
.aqua{color:#00bfbf}
.aqua-background{background:#00fafa}
.black{color:#000}
.black-background{background:#000}
.blue{color:#0000bf}
.blue-background{background:#0000fa}
.fuchsia{color:#bf00bf}
.fuchsia-background{background:#fa00fa}
.gray{color:#606060}
.gray-background{background:#7d7d7d}
.green{color:#006000}
.green-background{background:#007d00}
.lime{color:#00bf00}
.lime-background{background:#00fa00}
.maroon{color:#600000}
.maroon-background{background:#7d0000}
.navy{color:#000060}
.navy-background{background:#00007d}
.olive{color:#606000}
.olive-background{background:#7d7d00}
.purple{color:#600060}
.purple-background{background:#7d007d}
.red{color:#bf0000}
.red-background{background:#fa0000}
.silver{color:#909090}
.silver-background{background:#bcbcbc}
.teal{color:#006060}
.teal-background{background:#007d7d}
.white{color:#bfbfbf}
.white-background{background:#fafafa}
.yellow{color:#bfbf00}
.yellow-background{background:#fafa00}
span.icon>.fa{cursor:default}
a span.icon>.fa{cursor:inherit}
.admonitionblock td.icon [class^="fa icon-"]{font-size:2.5em;text-shadow:1px 1px 2px rgba(0,0,0,.5);cursor:default}
.admonitionblock td.icon .icon-note::before{content:"\f05a";color:#19407c}
.admonitionblock td.icon .icon-tip::before{content:"\f0eb";text-shadow:1px 1px 2px rgba(155,155,0,.8);color:#111}
.admonitionblock td.icon .icon-warning::before{content:"\f071";color:#bf6900}
.admonitionblock td.icon .icon-caution::before{content:"\f06d";color:#bf3400}
.admonitionblock td.icon .icon-important::before{content:"\f06a";color:#bf0000}
.conum[data-value]{display:inline-block;color:#fff!important;background:rgba(0,0,0,.8);border-radius:50%;text-align:center;font-size:.75em;width:1.67em;height:1.67em;line-height:1.67em;font-family:"Open Sans","DejaVu Sans",sans-serif;font-style:normal;font-weight:bold}
.conum[data-value] *{color:#fff!important}
.conum[data-value]+b{display:none}
.conum[data-value]::after{content:attr(data-value)}
pre .conum[data-value]{position:relative;top:-.125em}
b.conum *{color:inherit!important}
.conum:not([data-value]):empty{display:none}
dt,th.tableblock,td.content,div.footnote{text-rendering:optimizeLegibility}
h1,h2,p,td.content,span.alt,summary{letter-spacing:-.01em}
p strong,td.content strong,div.footnote strong{letter-spacing:-.005em}
p,blockquote,dt,td.content,span.alt,summary{font-size:1.0625rem}
p{margin-bottom:1.25rem}
.sidebarblock p,.sidebarblock dt,.sidebarblock td.content,p.tableblock{font-size:1em}
.exampleblock>.content{background:#fffef7;border-color:#e0e0dc;box-shadow:0 1px 4px #e0e0dc}
.print-only{display:none!important}
@page{margin:1.25cm .75cm}
@media print{*{box-shadow:none!important;text-shadow:none!important}
html{font-size:80%}
a{color:inherit!important;text-decoration:underline!important}
a.bare,a[href^="#"],a[href^="mailto:"]{text-decoration:none!important}
a[href^="http:"]:not(.bare)::after,a[href^="https:"]:not(.bare)::after{content:"(" attr(href) ")";display:inline-block;font-size:.875em;padding-left:.25em}
abbr[title]{border-bottom:1px dotted}
abbr[title]::after{content:" (" attr(title) ")"}
pre,blockquote,tr,img,object,svg{page-break-inside:avoid}
thead{display:table-header-group}
svg{max-width:100%}
p,blockquote,dt,td.content{font-size:1em;orphans:3;widows:3}
h2,h3,#toctitle,.sidebarblock>.content>.title{page-break-after:avoid}
#header,#content,#footnotes,#footer{max-width:none}
#toc,.sidebarblock,.exampleblock>.content{background:none!important}
#toc{border-bottom:1px solid #dddddf!important;padding-bottom:0!important}
body.book #header{text-align:center}
body.book #header>h1:first-child{border:0!important;margin:2.5em 0 1em}
body.book #header .details{border:0!important;display:block;padding:0!important}
body.book #header .details span:first-child{margin-left:0!important}
body.book #header .details br{display:block}
body.book #header .details br+span::before{content:none!important}
body.book #toc{border:0!important;text-align:left!important;padding:0!important;margin:0!important}
body.book #toc,body.book #preamble,body.book h1.sect0,body.book .sect1>h2{page-break-before:always}
.listingblock code[data-lang]::before{display:block}
#footer{padding:0 .9375em}
.hide-on-print{display:none!important}
.print-only{display:block!important}
.hide-for-print{display:none!important}
.show-for-print{display:inherit!important}}
@media amzn-kf8,print{#header>h1:first-child{margin-top:1.25rem}
.sect1{padding:0!important}
.sect1+.sect1{border:0}
#footer{background:none}
#footer-text{color:rgba(0,0,0,.6);font-size:.9em}}
@media amzn-kf8{#header,#content,#footnotes,#footer{padding:0}}
</style>
<style>
pre.rouge table td { padding: 5px; }
pre.rouge table pre { margin: 0; }
pre.rouge .cm {
color: #999988;
font-style: italic;
}
pre.rouge .cp {
color: #999999;
font-weight: bold;
}
pre.rouge .c1 {
color: #999988;
font-style: italic;
}
pre.rouge .cs {
color: #999999;
font-weight: bold;
font-style: italic;
}
pre.rouge .c, pre.rouge .ch, pre.rouge .cd, pre.rouge .cpf {
color: #999988;
font-style: italic;
}
pre.rouge .err {
color: #a61717;
background-color: #e3d2d2;
}
pre.rouge .gd {
color: #000000;
background-color: #ffdddd;
}
pre.rouge .ge {
color: #000000;
font-style: italic;
}
pre.rouge .gr {
color: #aa0000;
}
pre.rouge .gh {
color: #999999;
}
pre.rouge .gi {
color: #000000;
background-color: #ddffdd;
}
pre.rouge .go {
color: #888888;
}
pre.rouge .gp {
color: #555555;
}
pre.rouge .gs {
font-weight: bold;
}
pre.rouge .gu {
color: #aaaaaa;
}
pre.rouge .gt {
color: #aa0000;
}
pre.rouge .kc {
color: #000000;
font-weight: bold;
}
pre.rouge .kd {
color: #000000;
font-weight: bold;
}
pre.rouge .kn {
color: #000000;
font-weight: bold;
}
pre.rouge .kp {
color: #000000;
font-weight: bold;
}
pre.rouge .kr {
color: #000000;
font-weight: bold;
}
pre.rouge .kt {
color: #445588;
font-weight: bold;
}
pre.rouge .k, pre.rouge .kv {
color: #000000;
font-weight: bold;
}
pre.rouge .mf {
color: #009999;
}
pre.rouge .mh {
color: #009999;
}
pre.rouge .il {
color: #009999;
}
pre.rouge .mi {
color: #009999;
}
pre.rouge .mo {
color: #009999;
}
pre.rouge .m, pre.rouge .mb, pre.rouge .mx {
color: #009999;
}
pre.rouge .sa {
color: #000000;
font-weight: bold;
}
pre.rouge .sb {
color: #d14;
}
pre.rouge .sc {
color: #d14;
}
pre.rouge .sd {
color: #d14;
}
pre.rouge .s2 {
color: #d14;
}
pre.rouge .se {
color: #d14;
}
pre.rouge .sh {
color: #d14;
}
pre.rouge .si {
color: #d14;
}
pre.rouge .sx {
color: #d14;
}
pre.rouge .sr {
color: #009926;
}
pre.rouge .s1 {
color: #d14;
}
pre.rouge .ss {
color: #990073;
}
pre.rouge .s, pre.rouge .dl {
color: #d14;
}
pre.rouge .na {
color: #008080;
}
pre.rouge .bp {
color: #999999;
}
pre.rouge .nb {
color: #0086B3;
}
pre.rouge .nc {
color: #445588;
font-weight: bold;
}
pre.rouge .no {
color: #008080;
}
pre.rouge .nd {
color: #3c5d5d;
font-weight: bold;
}
pre.rouge .ni {
color: #800080;
}
pre.rouge .ne {
color: #990000;
font-weight: bold;
}
pre.rouge .nf, pre.rouge .fm {
color: #990000;
font-weight: bold;
}
pre.rouge .nl {
color: #990000;
font-weight: bold;
}
pre.rouge .nn {
color: #555555;
}
pre.rouge .nt {
color: #000080;
}
pre.rouge .vc {
color: #008080;
}
pre.rouge .vg {
color: #008080;
}
pre.rouge .vi {
color: #008080;
}
pre.rouge .nv, pre.rouge .vm {
color: #008080;
}
pre.rouge .ow {
color: #000000;
font-weight: bold;
}
pre.rouge .o {
color: #000000;
font-weight: bold;
}
pre.rouge .w {
color: #bbbbbb;
}
pre.rouge {
background-color: #f8f8f8;
}
</style>
</head>
<body class="article toc2 toc-left">
<div id="header">
<h1>Hash2: An Extensible Hashing Framework</h1>
<div class="details">
<span id="author" class="author">Peter Dimov</span><br>
</div>
<div id="toc" class="toc2">
<div id="toctitle">Table of Contents</div>
<ul class="sectlevel1">
<li><a href="#overview">Overview</a></li>
<li><a href="#hashing_bytes">Hashing Byte Sequences</a>
<ul class="sectlevel2">
<li><a href="#hashing_bytes_hash_algorithm_requirements">Hash Algorithm Requirements</a>
<ul class="sectlevel3">
<li><a href="#hashing_bytes_result_type">result_type</a></li>
<li><a href="#hashing_bytes_block_size">block_size</a></li>
<li><a href="#hashing_bytes_default_constructor">Default Constructor</a></li>
<li><a href="#hashing_bytes_constructor_taking_an_integer_seed">Constructor Taking an Integer Seed</a></li>
<li><a href="#hashing_bytes_constructor_taking_a_byte_sequence_seed">Constructor Taking a Byte Sequence Seed</a></li>
<li><a href="#hashing_bytes_copy_constructor_copy_assignment">Copy Constructor, Copy Assignment</a></li>
<li><a href="#hashing_bytes_update">update</a></li>
<li><a href="#hashing_bytes_result">result</a></li>
</ul>
</li>
<li><a href="#hashing_bytes_compile_time_hashing">Compile Time Hashing</a></li>
<li><a href="#hashing_bytes_provided_hash_algorithms">Provided Hash Algorithms</a>
<ul class="sectlevel3">
<li><a href="#hashing_bytes_fnv_1a">FNV-1a</a></li>
<li><a href="#hashing_bytes_xxhash">xxHash</a></li>
<li><a href="#hashing_bytes_siphash">SipHash</a></li>
<li><a href="#hashing_bytes_md5">MD5</a></li>
<li><a href="#hashing_bytes_sha_1">SHA-1</a></li>
<li><a href="#hashing_bytes_sha_2">SHA-2</a></li>
<li><a href="#hashing_bytes_ripemd_160_ripemd_128">RIPEMD-160, RIPEMD-128</a></li>
<li><a href="#hashing_bytes_hmac">HMAC</a></li>
</ul>
</li>
<li><a href="#hashing_bytes_choosing_a_hash_algorithm">Choosing a Hash Algorithm</a></li>
</ul>
</li>
<li><a href="#hashing_objects">Hashing C&#43;&#43; Objects</a></li>
<li><a href="#examples">Usage Examples</a>
<ul class="sectlevel2">
<li><a href="#example_md5sum">md5sum</a></li>
<li><a href="#example_hash2sum">hash2sum</a></li>
<li><a href="#example_compile_time_hashing">Compile Time Hashing</a></li>
</ul>
</li>
<li><a href="#implementation">Implementation Features</a>
<ul class="sectlevel2">
<li><a href="#implementation_supported_compilers">Supported Compilers</a></li>
</ul>
</li>
<li><a href="#reference">Reference</a>
<ul class="sectlevel2">
<li><a href="#ref_hash_algorithms">Hash Algorithms</a>
<ul class="sectlevel3">
<li><a href="#ref_fnv1a">&lt;boost/hash2/fnv1a.hpp&gt;</a>
<ul class="sectlevel4">
<li><a href="#ref_fnv1a_fnv1a_32">fnv1a_32</a></li>
<li><a href="#ref_fnv1a_fnv1a_64">fnv1a_64</a></li>
</ul>
</li>
<li><a href="#ref_xxhash">&lt;boost/hash2/xxhash.hpp&gt;</a>
<ul class="sectlevel4">
<li><a href="#ref_xxhash_xxhash_32">xxhash_32</a></li>
<li><a href="#ref_xxhash_xxhash_64">xxhash_64</a></li>
</ul>
</li>
<li><a href="#ref_siphash">&lt;boost/hash2/siphash.hpp&gt;</a>
<ul class="sectlevel4">
<li><a href="#ref_siphash_siphash_32">siphash_32</a></li>
<li><a href="#ref_siphash_siphash_64">siphash_64</a></li>
</ul>
</li>
<li><a href="#ref_hmac">&lt;boost/hash2/hmac.hpp&gt;</a>
<ul class="sectlevel4">
<li><a href="#ref_hmac_hmac">hmac</a></li>
</ul>
</li>
<li><a href="#ref_md5">&lt;boost/hash2/md5.hpp&gt;</a>
<ul class="sectlevel4">
<li><a href="#ref_md5_md5_128">md5_128</a></li>
</ul>
</li>
<li><a href="#ref_sha1">&lt;boost/hash2/sha1.hpp&gt;</a>
<ul class="sectlevel4">
<li><a href="#ref_sha1_sha1_160">sha1_160</a></li>
</ul>
</li>
<li><a href="#ref_sha2">&lt;boost/hash2/sha2.hpp&gt;</a>
<ul class="sectlevel4">
<li><a href="#ref_sha2_sha2_256">sha2_256</a></li>
<li><a href="#ref_sha2_sha2_224">sha2_224</a></li>
<li><a href="#ref_sha2_sha2_512">sha2_512</a></li>
<li><a href="#ref_sha2_sha2_384">sha2_384</a></li>
<li><a href="#ref_sha2_sha2_512_224">sha2_512_224</a></li>
<li><a href="#ref_sha2_sha2_512_256">sha2_512_256</a></li>
</ul>
</li>
<li><a href="#ref_ripemd">&lt;boost/hash2/ripemd.hpp&gt;</a>
<ul class="sectlevel4">
<li><a href="#ref_ripemd_ripemd_160">ripemd_160</a></li>
<li><a href="#ref_ripemd_ripemd_128">ripemd_128</a></li>
</ul>
</li>
</ul>
</li>
<li><a href="#ref_utilities_and_traits">Utilities and Traits</a>
<ul class="sectlevel3">
<li><a href="#ref_digest">&lt;boost/hash2/digest.hpp&gt;</a>
<ul class="sectlevel4">
<li><a href="#ref_digest_digest">digest</a></li>
</ul>
</li>
<li><a href="#ref_endian">&lt;boost/hash2/endian.hpp&gt;</a>
<ul class="sectlevel4">
<li><a href="#ref_endian_endian">endian</a></li>
</ul>
</li>
<li><a href="#ref_flavor">&lt;boost/hash2/flavor.hpp&gt;</a>
<ul class="sectlevel4">
<li><a href="#ref_flavor_default_flavor">default_flavor</a></li>
<li><a href="#ref_flavor_little_endian_flavor">little_endian_flavor</a></li>
<li><a href="#ref_flavor_big_endian_flavor">big_endian_flavor</a></li>
</ul>
</li>
<li><a href="#ref_get_integral_result">&lt;boost/hash2/get_integral_result.hpp&gt;</a>
<ul class="sectlevel4">
<li><a href="#ref_get_integral_result_get_integral_result">get_integral_result</a></li>
</ul>
</li>
<li><a href="#ref_is_trivially_equality_comparable">&lt;boost/hash2/is_trivially_equality_comparable.hpp&gt;</a>
<ul class="sectlevel4">
<li><a href="#ref_is_trivially_equality_comparable_is_trivially_equality_comparable">is_trivially_equality_comparable</a></li>
</ul>
</li>
<li><a href="#ref_is_endian_independent">&lt;boost/hash2/is_endian_independent.hpp&gt;</a>
<ul class="sectlevel4">
<li><a href="#ref_is_endian_independent_is_endian_independent">is_endian_independent</a></li>
</ul>
</li>
<li><a href="#ref_is_contiguously_hashable">&lt;boost/hash2/is_contiguously_hashable.hpp&gt;</a>
<ul class="sectlevel4">
<li><a href="#ref_is_contiguously_hashable_is_contiguously_hashable">is_contiguously_hashable</a></li>
</ul>
</li>
<li><a href="#ref_has_constant_size">&lt;boost/hash2/has_constant_size.hpp&gt;</a>
<ul class="sectlevel4">
<li><a href="#ref_has_constant_size_has_constant_size">has_constant_size</a></li>
</ul>
</li>
</ul>
</li>
<li><a href="#ref_hashing_cpp_objects">Hashing C&#43;&#43; Objects</a>
<ul class="sectlevel3">
<li><a href="#ref_hash_append_fwd">&lt;boost/hash2/hash_append_fwd.hpp&gt;</a>
<ul class="sectlevel4">
<li><a href="#ref_hash_append_fwd_synopsis">Synopsis</a></li>
</ul>
</li>
<li><a href="#ref_hash_append">&lt;boost/hash2/hash_append.hpp&gt;</a>
<ul class="sectlevel4">
<li><a href="#ref_hash_append_hash_append">hash_append</a></li>
<li><a href="#ref_hash_append_hash_append_range">hash_append_range</a></li>
<li><a href="#ref_hash_append_hash_append_size">hash_append_size</a></li>
<li><a href="#ref_hash_append_hash_append_sized_range">hash_append_sized_range</a></li>
<li><a href="#ref_hash_append_hash_append_unordered_range">hash_append_unordered_range</a></li>
<li><a href="#ref_hash_append_hash_append_tag">hash_append_tag</a></li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
<li><a href="#copyright">Copyright and License</a></li>
</ul>
</div>
</div>
<div id="content">
<div class="sect1">
<h2 id="overview">Overview</h2>
<div class="sectionbody">
<div class="paragraph">
<p>This library implements an extensible framework for implementing
hashing algorithms that can support user-defined types. Its structure
is largely based on the paper <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2014/n3980.html">"Types don&#8217;t know #"</a>
by Howard Hinnant, Vinnie Falco and John Bytheway.</p>
</div>
<div class="paragraph">
<p>The key feature of the design is the clean separation between the <em>hash
algorithm</em>, which takes an untyped stream of bytes (a <em>message</em>) and produces
a hash value (a <em>message digest</em>), and the <code>hash_append</code> function, which takes
a type and is responsible for turning the value of this type into a
sequence of bytes and feeding them to a <em>hash algorithm</em>.</p>
</div>
<div class="paragraph">
<p>This allows hashing support for user-defined types to be written once,
and then automatically being usable with any hash algorithms, even such
that weren&#8217;t yet available at the time the type was defined.</p>
</div>
<div class="paragraph">
<p>The following popular hashing algorithms are provided:</p>
</div>
<div class="ulist">
<ul>
<li>
<p><a href="https://en.wikipedia.org/wiki/Fowler%E2%80%93Noll%E2%80%93Vo_hash_function">FNV-1a</a></p>
</li>
<li>
<p><a href="https://cyan4973.github.io/xxHash/">xxHash</a></p>
</li>
<li>
<p><a href="https://en.wikipedia.org/wiki/SipHash">SipHash</a></p>
</li>
<li>
<p><a href="https://tools.ietf.org/html/rfc1321">MD5</a></p>
</li>
<li>
<p><a href="https://tools.ietf.org/html/rfc3174">SHA-1</a></p>
</li>
<li>
<p><a href="https://tools.ietf.org/html/rfc6234">SHA-2</a></p>
</li>
<li>
<p><a href="https://tools.ietf.org/html/rfc2104">HMAC-MD5, HMAC-SHA1, HMAC-SHA2</a></p>
</li>
<li>
<p><a href="https://homes.esat.kuleuven.be/%7Ebosselae/ripemd160.html">RIPEMD-160 and HMAC-RIPEMD-160</a></p>
</li>
</ul>
</div>
<div class="paragraph">
<p>but it&#8217;s also possible for users to write their own; as long as the
hash algorithm conforms to the concept, <code>hash_append</code> will work with it,
and so will all user-defined types that support <code>hash_append</code>.</p>
</div>
</div>
</div>
<div class="sect1">
<h2 id="hashing_bytes">Hashing Byte Sequences</h2>
<div class="sectionbody">
<div class="paragraph">
<p>This library addresses two major use cases: hashing an untyped sequence
of bytes, and hashing C&#43;&#43; objects.</p>
</div>
<div class="paragraph">
<p>Untyped byte sequences (also called <em>messages</em>) are hashed by passing
them to a <em>hash algorithm</em>, which then produces a hash value (or a
<em>message digest</em>).</p>
</div>
<div class="paragraph">
<p>The same <em>hash algorithm</em>, when passed the same <em>message</em>, will always
produce the same <em>digest</em>. (Published algorithms provide <em>message</em> and
corresponding <em>digest</em> pairs, called <em>test vectors</em>, to enable
verification of independent implementations.)</p>
</div>
<div class="paragraph">
<p>(To hash a C&#43;&#43; object, it&#8217;s first converted (serialized) to a sequence
of bytes, then passed to a <em>hash algorithm</em>.)</p>
</div>
<div class="sect2">
<h3 id="hashing_bytes_hash_algorithm_requirements">Hash Algorithm Requirements</h3>
<div class="paragraph">
<p>A <em>hash algorithm</em> must have the following structure, and meet the
following minimum requirements:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="rouge highlight"><code data-lang="c++"><span class="k">struct</span> <span class="nc">HashAlgorithm</span>
<span class="p">{</span>
<span class="k">using</span> <span class="n">result_type</span> <span class="o">=</span> <span class="cm">/*integral or array-like*/</span><span class="p">;</span>
<span class="k">static</span> <span class="k">constexpr</span> <span class="kt">int</span> <span class="n">block_size</span> <span class="o">=</span> <span class="cm">/*...*/</span><span class="p">;</span> <span class="c1">// optional</span>
<span class="n">HashAlgorithm</span><span class="p">();</span>
<span class="k">explicit</span> <span class="n">HashAlgorithm</span><span class="p">(</span> <span class="n">std</span><span class="o">::</span><span class="kt">uint64_t</span> <span class="n">seed</span> <span class="p">);</span>
<span class="n">HashAlgorithm</span><span class="p">(</span> <span class="kt">unsigned</span> <span class="kt">char</span> <span class="k">const</span><span class="o">*</span> <span class="n">seed</span><span class="p">,</span> <span class="n">std</span><span class="o">::</span><span class="kt">size_t</span> <span class="n">n</span> <span class="p">);</span>
<span class="n">HashAlgorithm</span><span class="p">(</span> <span class="n">HashAlgorithm</span> <span class="k">const</span><span class="o">&amp;</span> <span class="n">r</span> <span class="p">);</span>
<span class="n">HashAlgorithm</span><span class="o">&amp;</span> <span class="k">operator</span><span class="o">=</span><span class="p">(</span> <span class="n">HashAlgorithm</span> <span class="k">const</span><span class="o">&amp;</span> <span class="n">r</span> <span class="p">);</span>
<span class="kt">void</span> <span class="n">update</span><span class="p">(</span> <span class="kt">void</span> <span class="k">const</span><span class="o">*</span> <span class="n">data</span><span class="p">,</span> <span class="n">std</span><span class="o">::</span><span class="kt">size_t</span> <span class="n">n</span> <span class="p">);</span>
<span class="n">result_type</span> <span class="n">result</span><span class="p">();</span>
<span class="p">};</span></code></pre>
</div>
</div>
<div class="sect3">
<h4 id="hashing_bytes_result_type">result_type</h4>
<div class="paragraph">
<p>The nested type <code>result_type</code> is the type of the produced hash value. It
can be an unsigned integer type (that is not <code>bool</code>), typically
<code>std::uint32_t</code> or <code>std::uint64_t</code>, or a <code>std::array</code>-like type with a
value type of <code>unsigned char</code>.</p>
</div>
<div class="paragraph">
<p>Normally, non-cryptographic hash functions have an integer <code>result_type</code>,
and cryptographic hash functions have an array-like <code>result_type</code>, but
that&#8217;s not required.</p>
</div>
<div class="paragraph">
<p>The provided utility function <code>get_integral_result</code> can be used to obtain
an integer hash value from any valid <code>result_type</code>.</p>
</div>
</div>
<div class="sect3">
<h4 id="hashing_bytes_block_size">block_size</h4>
<div class="paragraph">
<p>Cryptographic hash functions provide a <code>block_size</code> value, which is their
block size (e.g. 64 for MD5, 128 for SHA2-512) and is required in order
to implement the corresponding <a href="https://en.wikipedia.org/wiki/HMAC">HMAC</a>.</p>
</div>
<div class="paragraph">
<p><code>block_size</code> is an optional requirement.</p>
</div>
</div>
<div class="sect3">
<h4 id="hashing_bytes_default_constructor">Default Constructor</h4>
<div class="paragraph">
<p>All <em>hash algorithms</em> must be default constructible. The default
constructor initializes the internal state of the hash algorithm to its
initial values, as published in its specification.</p>
</div>
<div class="paragraph">
<p>For example, the default constructor of <code>md5_128</code> corresponds to calling
the function <code>MD5_Init</code> of the reference implementation.</p>
</div>
</div>
<div class="sect3">
<h4 id="hashing_bytes_constructor_taking_an_integer_seed">Constructor Taking an Integer Seed</h4>
<div class="paragraph">
<p>All <em>hash algorithms</em> must be constructible from a value of type
<code>std::uint64_t</code>, which serves as a seed.</p>
</div>
<div class="paragraph">
<p>Using a seed value of 0 is equivalent to default construction.</p>
</div>
<div class="paragraph">
<p>Distinct seed values cause the internal state to be initialized differently,
and therefore, instances of the hash algorithm initialized by different seeds
produce different hash values when passed the same message.</p>
</div>
<div class="paragraph">
<p>Seeding using random (unobservable from the outside) values is useful for
preventing <a href="https://en.wikipedia.org/wiki/Collision_attack#Hash_flooding">hash flooding attacks</a>.</p>
</div>
</div>
<div class="sect3">
<h4 id="hashing_bytes_constructor_taking_a_byte_sequence_seed">Constructor Taking a Byte Sequence Seed</h4>
<div class="paragraph">
<p>All <em>hash algorithms</em> can be constructed from a seed sequence of
<code>unsigned char</code> values (this makes all hash algorithms
<a href="https://en.wikipedia.org/wiki/Keyed_hash_function">keyed hash functions</a>.)</p>
</div>
<div class="paragraph">
<p>A null sequence (one with length 0) produces a default-constructed instance.</p>
</div>
<div class="paragraph">
<p>Different seed sequences produce differently initialized instances.</p>
</div>
<div class="paragraph">
<p>While this requirement makes all hash algorithms usable as MACs
(<a href="https://en.wikipedia.org/wiki/Message_authentication_code">Message Authentication Codes</a>),
you should as a general rule prefer an established MAC algorithm, such as
<a href="https://en.wikipedia.org/wiki/HMAC">HMAC</a>. (A HMAC implementation is provided.)</p>
</div>
</div>
<div class="sect3">
<h4 id="hashing_bytes_copy_constructor_copy_assignment">Copy Constructor, Copy Assignment</h4>
<div class="paragraph">
<p>Hash algorithms are copy constructible and copy assignable, providing the
usual guarantees for these operations. That is, a copy is equivalent to the
original.</p>
</div>
</div>
<div class="sect3">
<h4 id="hashing_bytes_update">update</h4>
<div class="paragraph">
<p>The function <code>update</code> is the mechanism by which the input message is provided
to the hash algorithm.</p>
</div>
<div class="paragraph">
<p>Calling <code>update</code> several times is equivalent to calling it once with the
concatenated byte sequences from the individual calls. That is, the input
message may be provided in parts, and the way it&#8217;s split into parts does
not matter and does not affect the final hash value.</p>
</div>
<div class="paragraph">
<p>Given</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="rouge highlight"><code data-lang="c++"><span class="n">Hash</span> <span class="n">hash</span><span class="p">;</span> <span class="c1">// some hash algorithm</span>
<span class="kt">unsigned</span> <span class="kt">char</span> <span class="n">message</span><span class="p">[</span><span class="mi">6</span><span class="p">]</span> <span class="o">=</span> <span class="p">{</span> <span class="cm">/*...*/</span> <span class="p">};</span> <span class="c1">// some input message</span></code></pre>
</div>
</div>
<div class="paragraph">
<p>the following <code>update</code> call</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="rouge highlight"><code data-lang="c++"><span class="n">hash</span><span class="p">.</span><span class="n">update</span><span class="p">(</span> <span class="n">message</span><span class="p">,</span> <span class="mi">6</span> <span class="p">);</span></code></pre>
</div>
</div>
<div class="paragraph">
<p>is equivalent to</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="rouge highlight"><code data-lang="c++"><span class="n">hash</span><span class="p">.</span><span class="n">update</span><span class="p">(</span> <span class="n">message</span><span class="p">,</span> <span class="mi">4</span> <span class="p">);</span>
<span class="n">hash</span><span class="p">.</span><span class="n">update</span><span class="p">(</span> <span class="n">message</span> <span class="o">+</span> <span class="mi">4</span><span class="p">,</span> <span class="mi">2</span> <span class="p">);</span></code></pre>
</div>
</div>
<div class="paragraph">
<p>and to</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="rouge highlight"><code data-lang="c++"><span class="k">for</span><span class="p">(</span> <span class="kt">int</span> <span class="n">i</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span> <span class="n">i</span> <span class="o">&lt;</span> <span class="mi">6</span><span class="p">;</span> <span class="o">++</span><span class="n">i</span> <span class="p">)</span> <span class="n">hash</span><span class="p">.</span><span class="n">update</span><span class="p">(</span> <span class="o">&amp;</span><span class="n">message</span><span class="p">[</span><span class="n">i</span><span class="p">],</span> <span class="mi">1</span> <span class="p">);</span></code></pre>
</div>
</div>
</div>
<div class="sect3">
<h4 id="hashing_bytes_result">result</h4>
<div class="paragraph">
<p>After the entire input message has been provided via calls to <code>update</code>, the
final hash value can be obtained by calling <code>result</code>.</p>
</div>
<div class="paragraph">
<p>The call to <code>result</code> finalizes the internal state, by padding the message as
per the concrete algorithm specification, by optionally incorporating the
length of the message into the state, and by performing finalization
operations on the state, again as specified by the concrete algorithm.</p>
</div>
<div class="paragraph">
<p>A final hash value is then obtained by transforming the internal state, and
returned.</p>
</div>
<div class="paragraph">
<p>Note that <code>result</code> is non-const, because it changes the internal state. It&#8217;s
allowed for <code>result</code> to be called more than once; subsequent calls perform
the state finalization again and as a result produce a pseudorandom sequence
of <code>result_type</code> values. This can be used to effectively extend the output of
the hash function. For example, a 256 bit result can be obtained from a hash
algorithm whose <code>result_type</code> is 64 bit, by calling <code>result</code> four times.</p>
</div>
<div class="paragraph">
<p>As a toy example, <em>not intended for production use</em>, this is how one could
write a random number generator on top of the FNV-1a implementation provided
by the library:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="rouge highlight"><code data-lang="c++"><span class="n">std</span><span class="o">::</span><span class="kt">uint64_t</span> <span class="nf">random</span><span class="p">()</span>
<span class="p">{</span>
<span class="k">static</span> <span class="n">boost</span><span class="o">::</span><span class="n">hash2</span><span class="o">::</span><span class="n">fnv1a_64</span> <span class="n">hash</span><span class="p">;</span>
<span class="k">return</span> <span class="n">hash</span><span class="p">.</span><span class="n">result</span><span class="p">();</span>
<span class="p">}</span></code></pre>
</div>
</div>
</div>
</div>
<div class="sect2">
<h3 id="hashing_bytes_compile_time_hashing">Compile Time Hashing</h3>
<div class="paragraph">
<p>Under C&#43;&#43;14, it&#8217;s possible to invoke some hash algorithms at compile time.
These algorithms provide the following interface:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="rouge highlight"><code data-lang="c++"><span class="k">struct</span> <span class="nc">HashAlgorithm</span>
<span class="p">{</span>
<span class="k">using</span> <span class="n">result_type</span> <span class="o">=</span> <span class="cm">/*integral or array-like*/</span><span class="p">;</span>
<span class="k">static</span> <span class="k">constexpr</span> <span class="kt">int</span> <span class="n">block_size</span> <span class="o">=</span> <span class="cm">/*...*/</span><span class="p">;</span> <span class="c1">// optional</span>
<span class="k">constexpr</span> <span class="n">HashAlgorithm</span><span class="p">();</span>
<span class="k">explicit</span> <span class="k">constexpr</span> <span class="n">HashAlgorithm</span><span class="p">(</span> <span class="n">std</span><span class="o">::</span><span class="kt">uint64_t</span> <span class="n">seed</span> <span class="p">);</span>
<span class="k">constexpr</span> <span class="n">HashAlgorithm</span><span class="p">(</span> <span class="kt">unsigned</span> <span class="kt">char</span> <span class="k">const</span><span class="o">*</span> <span class="n">seed</span><span class="p">,</span> <span class="n">std</span><span class="o">::</span><span class="kt">size_t</span> <span class="n">n</span> <span class="p">);</span>
<span class="k">constexpr</span> <span class="n">HashAlgorithm</span><span class="p">(</span> <span class="n">HashAlgorithm</span> <span class="k">const</span><span class="o">&amp;</span> <span class="n">r</span> <span class="p">);</span>
<span class="k">constexpr</span> <span class="n">HashAlgorithm</span><span class="o">&amp;</span> <span class="k">operator</span><span class="o">=</span><span class="p">(</span> <span class="n">HashAlgorithm</span> <span class="k">const</span><span class="o">&amp;</span> <span class="n">r</span> <span class="p">);</span>
<span class="kt">void</span> <span class="n">update</span><span class="p">(</span> <span class="kt">void</span> <span class="k">const</span><span class="o">*</span> <span class="n">data</span><span class="p">,</span> <span class="n">std</span><span class="o">::</span><span class="kt">size_t</span> <span class="n">n</span> <span class="p">);</span>
<span class="k">constexpr</span> <span class="kt">void</span> <span class="n">update</span><span class="p">(</span> <span class="kt">unsigned</span> <span class="kt">char</span> <span class="k">const</span><span class="o">*</span> <span class="n">data</span><span class="p">,</span> <span class="n">std</span><span class="o">::</span><span class="kt">size_t</span> <span class="n">n</span> <span class="p">);</span>
<span class="k">constexpr</span> <span class="n">result_type</span> <span class="n">result</span><span class="p">();</span>
<span class="p">};</span></code></pre>
</div>
</div>
<div class="paragraph">
<p>Apart from the added <code>constexpr</code> qualifiers, the only difference is that
<code>update</code> has a second overload that takes <code>unsigned char const*</code> instead
of <code>void const*</code>. (Pointers to <code>void</code> cannot be used in <code>constexpr</code> functions
before C&#43;&#43;26.)</p>
</div>
</div>
<div class="sect2">
<h3 id="hashing_bytes_provided_hash_algorithms">Provided Hash Algorithms</h3>
<div class="sect3">
<h4 id="hashing_bytes_fnv_1a">FNV-1a</h4>
<div class="paragraph">
<p>The <a href="https://en.wikipedia.org/wiki/Fowler%E2%80%93Noll%E2%80%93Vo_hash_function">Fowler-Noll-Vo hash function</a>
is provided as a representative of the class of hash functions that process
their output one byte at a time. The 32 or 64 bit state is updated for each
input character <code>ch</code> by using the operation <code>state = (state ^ ch) * fnv_prime</code>.</p>
</div>
<div class="paragraph">
<p>FNV-1a is non-cryptographic, relatively weak compared to state of the art
hash functions (although good for its class), but fast when the input strings
are short.</p>
</div>
</div>
<div class="sect3">
<h4 id="hashing_bytes_xxhash">xxHash</h4>
<div class="paragraph">
<p><a href="https://xxhash.com/">xxHash</a> is a fast non-cryptographic hashing algorithm by Yann Collet.</p>
</div>
<div class="paragraph">
<p>Its speed (~5GB/s for <code>xxhash_32</code>, ~10GB/s for <code>xxhash_64</code> on a Xeon E5-2683 v4 @ 2.10GHz)
makes it well suited for quick generation of file or data integrity checksums.</p>
</div>
</div>
<div class="sect3">
<h4 id="hashing_bytes_siphash">SipHash</h4>
<div class="paragraph">
<p><a href="https://en.wikipedia.org/wiki/SipHash">SipHash</a> by Jean-Philippe Aumasson and Daniel J. Bernstein
(<a href="https://eprint.iacr.org/2012/351">paper</a>) has been designed to thwart
<a href="https://en.wikipedia.org/wiki/Collision_attack#Hash_flooding">hash flooding attacks</a> against hash tables that receive
external untrusted input (e.g. HTTP message headers, or JSON objects.)</p>
</div>
<div class="paragraph">
<p>It&#8217;s not a cryptographic hash function (even though its design is similar to one),
because it does not provide collision resistance when the initial seed is known.</p>
</div>
<div class="paragraph">
<p>It is, however, a cryptographically strong keyed hash function (or a pseudorandom function, PRF).
If the initial seed is unknown to the attacker, it&#8217;s computationally difficult to engineer a collision, or to recover the seed by observing the output.</p>
</div>
<div class="paragraph">
<p>SipHash has been adopted as the de-facto standard hash function for hash tables that can be exposed to external input,
and is used in Python, Perl, Ruby, Rust, and other languages.</p>
</div>
<div class="paragraph">
<p>SipHash is the recommended hash function for hash tables exposed to external input. As a best practice, it should be seeded with a random value that varies per connection, and not a fixed one per process.</p>
</div>
</div>
<div class="sect3">
<h4 id="hashing_bytes_md5">MD5</h4>
<div class="paragraph">
<p>Designed in 1991 by Ron Rivest, <a href="https://en.wikipedia.org/wiki/MD5">MD5</a> used
to be the best known and the most widely used <a href="https://en.wikipedia.org/wiki/Cryptographic_hash_function">cryptographic hash function</a>,
but has been broken and is no longer considered cryptographic for any purposes.
It produces a 128 bit digest.</p>
</div>
<div class="paragraph">
<p>MD5 should no longer be used in new code when cryptographic strength is required, except when implementing an existing
specification or protocol that calls for its use.</p>
</div>
<div class="paragraph">
<p>Prefer SHA2-512/256 (or SHA2-256 in 32 bit code) instead.</p>
</div>
<div class="paragraph">
<p>If you require a digest of exactly 128 bits, use RIPEMD-128 instead.
Do note that 128 bit digests are no longer considered cryptographic, because attacks with a complexity of 2<sup>64</sup> are within the capabilities of well-funded attackers.</p>
</div>
</div>
<div class="sect3">
<h4 id="hashing_bytes_sha_1">SHA-1</h4>
<div class="paragraph">
<p><a href="https://en.wikipedia.org/wiki/SHA-1">SHA-1</a> is a cryptographic hash function that was designed by NSA and
<a href="https://csrc.nist.gov/pubs/fips/180-1/final">published</a> in 1995 by <a href="https://en.wikipedia.org/wiki/NIST">NIST</a>
as a <a href="https://en.wikipedia.org/wiki/Federal_Information_Processing_Standard">Federal Information Processing Standard</a> (FIPS).
It produces a 160 bit digest.</p>
</div>
<div class="paragraph">
<p>SHA-1 is now considered insecure against a well-funded attacker, and should no
longer be used in new code. Prefer SHA2-512/256, SHA2-256 in 32 bit code, or, if
you require a digest of exactly 160 bits, RIPEMD-160 instead.</p>
</div>
</div>
<div class="sect3">
<h4 id="hashing_bytes_sha_2">SHA-2</h4>
<div class="paragraph">
<p><a href="https://en.wikipedia.org/wiki/SHA-2">SHA-2</a> is a family of cryptographic hash functions, also designed by NSA,
<a href="https://csrc.nist.gov/pubs/fips/180-2/upd1/final">initially published</a> by NIST in 2002,
and <a href="https://csrc.nist.gov/pubs/fips/180-4/upd1/final">updated</a> in 2015.
It includes SHA2-224, SHA2-256, SHA2-384, SHA2-512, SHA2-512/224, and SHA2-512/256, each producing a digest with the corresponding bit length.</p>
</div>
<div class="paragraph">
<p>Of these, SHA2-256 and SHA2-512 are the basis ones, and the rest are variants with the digest truncated.</p>
</div>
<div class="paragraph">
<p>The SHA-2 functions haven&#8217;t been broken and are in wide use, despite the existence of a newer standard (SHA-3).</p>
</div>
<div class="paragraph">
<p>SHA2-256 and its truncated variant SHA2-224 use 32 bit operations and therefore do not lose performance on a 32 bit platform.</p>
</div>
<div class="paragraph">
<p>SHA2-512 and its truncated variants SHA2-384, SHA2-512/224, and SHA2-512/256 use 64 bit operations and are approximately 1.5 times as fast
as SHA2-256 on a 64 bit platform, but twice as slow in 32 bit code.</p>
</div>
<div class="paragraph">
<p>On 64 bit platforms, SHA2-512/256 and SHA2-512/224 should be preferred over SHA2-256 and SHA2-224 not just because of speed, but because
they are resistant to length extension attacks as they don&#8217;t expose all of the bits of their internal state in the final digest.</p>
</div>
</div>
<div class="sect3">
<h4 id="hashing_bytes_ripemd_160_ripemd_128">RIPEMD-160, RIPEMD-128</h4>
<div class="paragraph">
<p>Designed in 1996, <a href="https://en.wikipedia.org/wiki/RIPEMD">RIPEMD-160</a> is a cryptographic hash function that was less well known than MD5 and SHA-1,
but that has recently become popular because of its use in Bitcoin and other cryptocurrencies.</p>
</div>
<div class="paragraph">
<p>Even though it hasn&#8217;t been broken, there&#8217;s no reason to prefer its use in new code over SHA-2.</p>
</div>
<div class="paragraph">
<p>RIPEMD-128 is a truncated variant of RIPEMD-160. (Do note that 128 bit digests are no longer considered cryptographic, because attacks with a complexity of 2<sup>64</sup> are within the capabilities of well-funded attackers.)</p>
</div>
</div>
<div class="sect3">
<h4 id="hashing_bytes_hmac">HMAC</h4>
<div class="paragraph">
<p><a href="https://en.wikipedia.org/wiki/HMAC">HMAC</a> (Hash-based Message Authentication Code) is an algorithm for deriving
a <em>message authentication code</em> by using a cryptographic hash function. It&#8217;s described in <a href="https://datatracker.ietf.org/doc/html/rfc2104">RFC 2104</a>.</p>
</div>
<div class="paragraph">
<p>A message authentication code differs from a digest by the fact that it depends on both the contents of the message
and on a secret <em>key</em>; in contrast, a message digest only depends on the contents of the message.</p>
</div>
<div class="paragraph">
<p>Even though all hash algorithms provided by the library can be used to produce message authentication codes,
by means of seeding the hash algorithm initially with a secret key by calling the constructor taking a byte
sequence, hash algorithms have usually not been designed to be used in this manner, and such use hasn&#8217;t been
cryptographically analyzed and vetted. (SipHash is an exception; it has specifically been designed as a MAC.)</p>
</div>
<div class="paragraph">
<p>The HMAC algorithm is provided in the form of a class template <code>hmac&lt;H&gt;</code> that adapts a cryptographic hash
algorithm <code>H</code>. <code>hmac&lt;H&gt;</code> satisfies the requirements of a cryptographic hash algorithm.</p>
</div>
<div class="paragraph">
<p>Convenience aliases of common HMAC instantiations are provided. For example, the <code>md5.hpp</code> header defining
<code>md5_128</code> also defines <code>hmac_md5_128</code> as an alias to <code>hmac&lt;md5_128&gt;</code>.</p>
</div>
</div>
</div>
<div class="sect2">
<h3 id="hashing_bytes_choosing_a_hash_algorithm">Choosing a Hash Algorithm</h3>
<div class="paragraph">
<p>&#8230;&#8203;</p>
</div>
</div>
</div>
</div>
<div class="sect1">
<h2 id="hashing_objects">Hashing C&#43;&#43; Objects</h2>
<div class="sectionbody">
<div class="paragraph">
<p>The traditional approach to hashing C&#43;&#43; objects is to make
them responsible for providing a hash value. The standard,
for instance, follows this by making it the responsibility
of each type <code>T</code> to implement a specialization of <code>std::hash&lt;T&gt;</code>,
which when invoked with a value returns its <code>size_t</code> hash.</p>
</div>
<div class="paragraph">
<p>This, of course, means that the specific hash algorithm varies
per type and is, in the general case, completely opaque.</p>
</div>
<div class="paragraph">
<p>This library takes a different approach; the hash algorithm
is known and chosen by the user. A C&#43;&#43; object is hashed by
first being converted to a sequence of bytes representing its
value (a <em>message</em>) which is then passed to the hash algorithm.</p>
</div>
<div class="paragraph">
<p>The conversion must obey the following requirements:</p>
</div>
<div class="ulist">
<ul>
<li>
<p>Equal objects must produce the same message;</p>
</li>
<li>
<p>Different objects should produce different messages;</p>
</li>
<li>
<p>An object should always produce a non-empty message.</p>
</li>
</ul>
</div>
<div class="paragraph">
<p>The first two requirements follow directly from the hash value
requirements, whereas the third one is a bit more subtle and
is intended to prevent things like the distinct sequences
<code>[[1], [], []]</code> and <code>[[], [1], []]</code> producing the same message.
(This is similar to the requirement that all C&#43;&#43; objects have
<code>sizeof</code> that is not zero, including empty ones.)</p>
</div>
<div class="paragraph">
<p>In this library, the conversion is performed by the function
<code>hash_append</code>. It&#8217;s declared as follows:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="rouge highlight"><code data-lang="c++"><span class="k">template</span><span class="o">&lt;</span><span class="k">class</span> <span class="nc">Hash</span><span class="p">,</span> <span class="k">class</span> <span class="nc">Flavor</span> <span class="o">=</span> <span class="n">default_flavor</span><span class="p">,</span> <span class="k">class</span> <span class="nc">T</span><span class="p">&gt;</span>
<span class="k">constexpr</span> <span class="kt">void</span> <span class="nf">hash_append</span><span class="p">(</span> <span class="n">Hash</span><span class="o">&amp;</span> <span class="n">h</span><span class="p">,</span> <span class="n">Flavor</span> <span class="k">const</span><span class="o">&amp;</span> <span class="n">f</span><span class="p">,</span> <span class="n">T</span> <span class="k">const</span><span class="o">&amp;</span> <span class="n">v</span> <span class="p">);</span></code></pre>
</div>
</div>
<div class="paragraph">
<p>and the effect of invoking <code>hash_append(h, f, v)</code> is to call
<code>h.update(p, n)</code> one or more times (but never zero times.) The
combined result of these calls forms the message corresponding
to <code>v</code>.</p>
</div>
<div class="paragraph">
<p><code>hash_append</code> handles natively the following types <code>T</code>:</p>
</div>
<div class="ulist">
<ul>
<li>
<p>Integral types (signed and unsigned integers, character types, <code>bool</code>);</p>
</li>
<li>
<p>Floating point types (<code>float</code> and <code>double</code>);</p>
</li>
<li>
<p>Enumeration types;</p>
</li>
<li>
<p>Pointer types (object and function, but not pointer to member types);</p>
</li>
<li>
<p>C arrays;</p>
</li>
<li>
<p>Containers and ranges (types that provide <code>begin()</code> and <code>end()</code>;</p>
</li>
<li>
<p>Unordered containers and ranges;</p>
</li>
<li>
<p>Constant size containers (<code>std::array</code>, <code>boost::array</code>);</p>
</li>
<li>
<p>Tuple-like types (<code>std::pair</code>, <code>std::tuple</code>);</p>
</li>
<li>
<p>Described classes (using Boost.Describe).</p>
</li>
</ul>
</div>
<div class="paragraph">
<p>User-defined types that aren&#8217;t in the above categories can provide
support for <code>hash_append</code> by declaring an overload of the <code>tag_invoke</code>
function with the appropriate parameters.</p>
</div>
<div class="paragraph">
<p>The second argument to <code>hash_append</code>, the <em>flavor</em>, is used to control
the serialization process in cases where more than one behavior is
possible and desirable. It currently contains the following members:</p>
</div>
<div class="ulist">
<ul>
<li>
<p><code>static constexpr endian byte_order; // native, little, or big</code></p>
</li>
<li>
<p><code>using size_type = std::uint64_t; // or std::uint32_t</code></p>
</li>
</ul>
</div>
<div class="paragraph">
<p>The <code>byte_order</code> member of the flavor affects how scalar C&#43;&#43; objects
are serialized into bytes. For example, the <code>uint32_t</code> integer <code>0x01020304</code>
can be serialized into <code>{ 0x01, 0x02, 0x03, 0x04 }</code> when <code>byte_order</code> is
<code>endian::big</code>, and into <code>{ 0x04, 0x03, 0x02, 0x01 }</code> when <code>byte_order</code>
is <code>endian::little</code>.</p>
</div>
<div class="paragraph">
<p>The value <code>endian::native</code> means to use the byte order of the current
platform. This typically results in higher performance, because it allows
<code>hash_append</code> to pass the underlying object bytes directly to the hash
algorithm, without any processing.</p>
</div>
<div class="paragraph">
<p>The <code>size_type</code> member type of the flavor affects how container and range
sizes (typically of type <code>size_t</code>) are serialized. Since the size of
<code>size_t</code> in bytes can vary, serializing the type directly results in
different hash values when the code is compiled for 64 bit or for 32 bit.
Using a fixed width type avoids this.</p>
</div>
<div class="paragraph">
<p>There are three predefined flavors, defined in <code>boost/hash2/flavor.hpp</code>:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="rouge highlight"><code data-lang="c++"><span class="k">struct</span> <span class="nc">default_flavor</span>
<span class="p">{</span>
<span class="k">using</span> <span class="n">size_type</span> <span class="o">=</span> <span class="n">std</span><span class="o">::</span><span class="kt">uint64_t</span><span class="p">;</span>
<span class="k">static</span> <span class="k">constexpr</span> <span class="k">auto</span> <span class="n">byte_order</span> <span class="o">=</span> <span class="n">endian</span><span class="o">::</span><span class="n">native</span><span class="p">;</span>
<span class="p">};</span>
<span class="k">struct</span> <span class="nc">little_endian_flavor</span>
<span class="p">{</span>
<span class="k">using</span> <span class="n">size_type</span> <span class="o">=</span> <span class="n">std</span><span class="o">::</span><span class="kt">uint64_t</span><span class="p">;</span>
<span class="k">static</span> <span class="k">constexpr</span> <span class="k">auto</span> <span class="n">byte_order</span> <span class="o">=</span> <span class="n">endian</span><span class="o">::</span><span class="n">little</span><span class="p">;</span>
<span class="p">};</span>
<span class="k">struct</span> <span class="nc">big_endian_flavor</span>
<span class="p">{</span>
<span class="k">using</span> <span class="n">size_type</span> <span class="o">=</span> <span class="n">std</span><span class="o">::</span><span class="kt">uint64_t</span><span class="p">;</span>
<span class="k">static</span> <span class="k">constexpr</span> <span class="k">auto</span> <span class="n">byte_order</span> <span class="o">=</span> <span class="n">endian</span><span class="o">::</span><span class="n">big</span><span class="p">;</span>
<span class="p">};</span></code></pre>
</div>
</div>
<div class="paragraph">
<p>The default one is used when <code>hash_append</code> is invoked without passing
a flavor: <code>hash_append(h, {}, v);</code>. It results in higher performance,
but the hash values are endianness dependent.</p>
</div>
</div>
</div>
<div class="sect1">
<h2 id="examples">Usage Examples</h2>
<div class="sectionbody">
<div class="sect2">
<h3 id="example_md5sum">md5sum</h3>
<div class="paragraph">
<p>A command line utility that prints the MD5 digests
of a list of files passed as arguments.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="rouge highlight"><code data-lang="c++"><span class="cp">#include</span> <span class="cpf">&lt;boost/hash2/md5.hpp&gt;</span><span class="cp">
#include</span> <span class="cpf">&lt;array&gt;</span><span class="cp">
#include</span> <span class="cpf">&lt;string&gt;</span><span class="cp">
#include</span> <span class="cpf">&lt;cerrno&gt;</span><span class="cp">
#include</span> <span class="cpf">&lt;cstdio&gt;</span><span class="cp">
</span>
<span class="k">static</span> <span class="kt">void</span> <span class="nf">md5sum</span><span class="p">(</span> <span class="n">std</span><span class="o">::</span><span class="kt">FILE</span><span class="o">*</span> <span class="n">f</span><span class="p">,</span> <span class="kt">char</span> <span class="k">const</span><span class="o">*</span> <span class="n">fn</span> <span class="p">)</span>
<span class="p">{</span>
<span class="n">boost</span><span class="o">::</span><span class="n">hash2</span><span class="o">::</span><span class="n">md5_128</span> <span class="n">hash</span><span class="p">;</span>
<span class="kt">int</span> <span class="k">const</span> <span class="n">N</span> <span class="o">=</span> <span class="mi">4096</span><span class="p">;</span>
<span class="kt">unsigned</span> <span class="kt">char</span> <span class="n">buffer</span><span class="p">[</span> <span class="n">N</span> <span class="p">];</span>
<span class="k">for</span><span class="p">(</span> <span class="p">;;</span> <span class="p">)</span>
<span class="p">{</span>
<span class="n">std</span><span class="o">::</span><span class="kt">size_t</span> <span class="n">n</span> <span class="o">=</span> <span class="n">std</span><span class="o">::</span><span class="n">fread</span><span class="p">(</span> <span class="n">buffer</span><span class="p">,</span> <span class="mi">1</span><span class="p">,</span> <span class="n">N</span><span class="p">,</span> <span class="n">f</span> <span class="p">);</span>
<span class="k">if</span><span class="p">(</span> <span class="n">std</span><span class="o">::</span><span class="n">ferror</span><span class="p">(</span> <span class="n">f</span> <span class="p">)</span> <span class="p">)</span>
<span class="p">{</span>
<span class="n">std</span><span class="o">::</span><span class="n">fprintf</span><span class="p">(</span> <span class="n">stderr</span><span class="p">,</span> <span class="s">"'%s': read error: %s</span><span class="se">\n</span><span class="s">"</span><span class="p">,</span> <span class="n">fn</span><span class="p">,</span> <span class="n">std</span><span class="o">::</span><span class="n">strerror</span><span class="p">(</span> <span class="n">errno</span> <span class="p">)</span> <span class="p">);</span>
<span class="k">return</span><span class="p">;</span>
<span class="p">}</span>
<span class="k">if</span><span class="p">(</span> <span class="n">n</span> <span class="o">==</span> <span class="mi">0</span> <span class="p">)</span> <span class="k">break</span><span class="p">;</span>
<span class="n">hash</span><span class="p">.</span><span class="n">update</span><span class="p">(</span> <span class="n">buffer</span><span class="p">,</span> <span class="n">n</span> <span class="p">);</span>
<span class="p">}</span>
<span class="n">std</span><span class="o">::</span><span class="n">string</span> <span class="n">digest</span> <span class="o">=</span> <span class="n">to_string</span><span class="p">(</span> <span class="n">hash</span><span class="p">.</span><span class="n">result</span><span class="p">()</span> <span class="p">);</span>
<span class="n">std</span><span class="o">::</span><span class="n">printf</span><span class="p">(</span> <span class="s">"%s *%s</span><span class="se">\n</span><span class="s">"</span><span class="p">,</span> <span class="n">digest</span><span class="p">.</span><span class="n">c_str</span><span class="p">(),</span> <span class="n">fn</span> <span class="p">);</span>
<span class="p">}</span>
<span class="kt">int</span> <span class="n">main</span><span class="p">(</span> <span class="kt">int</span> <span class="n">argc</span><span class="p">,</span> <span class="kt">char</span> <span class="k">const</span><span class="o">*</span> <span class="n">argv</span><span class="p">[]</span> <span class="p">)</span>
<span class="p">{</span>
<span class="k">for</span><span class="p">(</span> <span class="kt">int</span> <span class="n">i</span> <span class="o">=</span> <span class="mi">1</span><span class="p">;</span> <span class="n">i</span> <span class="o">&lt;</span> <span class="n">argc</span><span class="p">;</span> <span class="o">++</span><span class="n">i</span> <span class="p">)</span>
<span class="p">{</span>
<span class="n">std</span><span class="o">::</span><span class="kt">FILE</span><span class="o">*</span> <span class="n">f</span> <span class="o">=</span> <span class="n">std</span><span class="o">::</span><span class="n">fopen</span><span class="p">(</span> <span class="n">argv</span><span class="p">[</span><span class="n">i</span><span class="p">],</span> <span class="s">"rb"</span> <span class="p">);</span>
<span class="k">if</span><span class="p">(</span> <span class="n">f</span> <span class="o">==</span> <span class="mi">0</span> <span class="p">)</span>
<span class="p">{</span>
<span class="n">std</span><span class="o">::</span><span class="n">fprintf</span><span class="p">(</span> <span class="n">stderr</span><span class="p">,</span> <span class="s">"'%s': open error: %s</span><span class="se">\n</span><span class="s">"</span><span class="p">,</span> <span class="n">argv</span><span class="p">[</span><span class="n">i</span><span class="p">],</span> <span class="n">std</span><span class="o">::</span><span class="n">strerror</span><span class="p">(</span> <span class="n">errno</span> <span class="p">)</span> <span class="p">);</span>
<span class="k">continue</span><span class="p">;</span>
<span class="p">}</span>
<span class="n">md5sum</span><span class="p">(</span> <span class="n">f</span><span class="p">,</span> <span class="n">argv</span><span class="p">[</span><span class="n">i</span><span class="p">]</span> <span class="p">);</span>
<span class="n">std</span><span class="o">::</span><span class="n">fclose</span><span class="p">(</span> <span class="n">f</span> <span class="p">);</span>
<span class="p">}</span>
<span class="p">}</span></code></pre>
</div>
</div>
<div class="paragraph">
<p>Sample command:</p>
</div>
<div class="listingblock">
<div class="content">
<pre>md5sum apache_builds.json canada.json citm_catalog.json twitter.json</pre>
</div>
</div>
<div class="paragraph">
<p>Sample output:</p>
</div>
<div class="listingblock">
<div class="content">
<pre>7dc25b5fd9eb2217ed648dad23b311da *apache_builds.json
8767d618bff99552b4946078d3a90c0c *canada.json
b4391581160654374bee934a3b91255e *citm_catalog.json
bf7d37451840af4e8873b65763315cbf *twitter.json</pre>
</div>
</div>
</div>
<div class="sect2">
<h3 id="example_hash2sum">hash2sum</h3>
<div class="paragraph">
<p>A command line utility that prints the digests
of a list of files, using a specified hash algorithm.</p>
</div>
<div class="paragraph">
<p>The hash algorithm is passed as the first command
line argument.</p>
</div>
<div class="paragraph">
<p>This example requires C&#43;&#43;14.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="rouge highlight"><code data-lang="c++"><span class="cp">#include</span> <span class="cpf">&lt;boost/hash2/md5.hpp&gt;</span><span class="cp">
#include</span> <span class="cpf">&lt;boost/hash2/sha1.hpp&gt;</span><span class="cp">
#include</span> <span class="cpf">&lt;boost/hash2/sha2.hpp&gt;</span><span class="cp">
#include</span> <span class="cpf">&lt;boost/hash2/ripemd.hpp&gt;</span><span class="cp">
#include</span> <span class="cpf">&lt;boost/mp11.hpp&gt;</span><span class="cp">
#include</span> <span class="cpf">&lt;array&gt;</span><span class="cp">
#include</span> <span class="cpf">&lt;string&gt;</span><span class="cp">
#include</span> <span class="cpf">&lt;cerrno&gt;</span><span class="cp">
#include</span> <span class="cpf">&lt;cstdio&gt;</span><span class="cp">
</span>
<span class="k">template</span><span class="o">&lt;</span><span class="k">class</span> <span class="nc">Hash</span><span class="p">&gt;</span> <span class="kt">void</span> <span class="nf">hash2sum</span><span class="p">(</span> <span class="n">std</span><span class="o">::</span><span class="kt">FILE</span><span class="o">*</span> <span class="n">f</span><span class="p">,</span> <span class="kt">char</span> <span class="k">const</span><span class="o">*</span> <span class="n">fn</span> <span class="p">)</span>
<span class="p">{</span>
<span class="n">Hash</span> <span class="n">hash</span><span class="p">;</span>
<span class="kt">int</span> <span class="k">const</span> <span class="n">N</span> <span class="o">=</span> <span class="mi">4096</span><span class="p">;</span>
<span class="kt">unsigned</span> <span class="kt">char</span> <span class="n">buffer</span><span class="p">[</span> <span class="n">N</span> <span class="p">];</span>
<span class="k">for</span><span class="p">(</span> <span class="p">;;</span> <span class="p">)</span>
<span class="p">{</span>
<span class="n">std</span><span class="o">::</span><span class="kt">size_t</span> <span class="n">n</span> <span class="o">=</span> <span class="n">std</span><span class="o">::</span><span class="n">fread</span><span class="p">(</span> <span class="n">buffer</span><span class="p">,</span> <span class="mi">1</span><span class="p">,</span> <span class="n">N</span><span class="p">,</span> <span class="n">f</span> <span class="p">);</span>
<span class="k">if</span><span class="p">(</span> <span class="n">std</span><span class="o">::</span><span class="n">ferror</span><span class="p">(</span> <span class="n">f</span> <span class="p">)</span> <span class="p">)</span>
<span class="p">{</span>
<span class="n">std</span><span class="o">::</span><span class="n">fprintf</span><span class="p">(</span> <span class="n">stderr</span><span class="p">,</span> <span class="s">"'%s': read error: %s</span><span class="se">\n</span><span class="s">"</span><span class="p">,</span> <span class="n">fn</span><span class="p">,</span> <span class="n">std</span><span class="o">::</span><span class="n">strerror</span><span class="p">(</span> <span class="n">errno</span> <span class="p">)</span> <span class="p">);</span>
<span class="k">return</span><span class="p">;</span>
<span class="p">}</span>
<span class="k">if</span><span class="p">(</span> <span class="n">n</span> <span class="o">==</span> <span class="mi">0</span> <span class="p">)</span> <span class="k">break</span><span class="p">;</span>
<span class="n">hash</span><span class="p">.</span><span class="n">update</span><span class="p">(</span> <span class="n">buffer</span><span class="p">,</span> <span class="n">n</span> <span class="p">);</span>
<span class="p">}</span>
<span class="n">std</span><span class="o">::</span><span class="n">string</span> <span class="n">digest</span> <span class="o">=</span> <span class="n">to_string</span><span class="p">(</span> <span class="n">hash</span><span class="p">.</span><span class="n">result</span><span class="p">()</span> <span class="p">);</span>
<span class="n">std</span><span class="o">::</span><span class="n">printf</span><span class="p">(</span> <span class="s">"%s *%s</span><span class="se">\n</span><span class="s">"</span><span class="p">,</span> <span class="n">digest</span><span class="p">.</span><span class="n">c_str</span><span class="p">(),</span> <span class="n">fn</span> <span class="p">);</span>
<span class="p">}</span>
<span class="k">template</span><span class="o">&lt;</span><span class="k">class</span> <span class="nc">Hash</span><span class="p">&gt;</span> <span class="kt">void</span> <span class="n">hash2sum</span><span class="p">(</span> <span class="kt">char</span> <span class="k">const</span><span class="o">*</span> <span class="n">fn</span> <span class="p">)</span>
<span class="p">{</span>
<span class="n">std</span><span class="o">::</span><span class="kt">FILE</span><span class="o">*</span> <span class="n">f</span> <span class="o">=</span> <span class="n">std</span><span class="o">::</span><span class="n">fopen</span><span class="p">(</span> <span class="n">fn</span><span class="p">,</span> <span class="s">"rb"</span> <span class="p">);</span>
<span class="k">if</span><span class="p">(</span> <span class="n">f</span> <span class="o">==</span> <span class="mi">0</span> <span class="p">)</span>
<span class="p">{</span>
<span class="n">std</span><span class="o">::</span><span class="n">fprintf</span><span class="p">(</span> <span class="n">stderr</span><span class="p">,</span> <span class="s">"'%s': open error: %s</span><span class="se">\n</span><span class="s">"</span><span class="p">,</span> <span class="n">fn</span><span class="p">,</span> <span class="n">std</span><span class="o">::</span><span class="n">strerror</span><span class="p">(</span> <span class="n">errno</span> <span class="p">)</span> <span class="p">);</span>
<span class="p">}</span>
<span class="k">else</span>
<span class="p">{</span>
<span class="n">hash2sum</span><span class="o">&lt;</span><span class="n">Hash</span><span class="o">&gt;</span><span class="p">(</span> <span class="n">f</span><span class="p">,</span> <span class="n">fn</span> <span class="p">);</span>
<span class="n">std</span><span class="o">::</span><span class="n">fclose</span><span class="p">(</span> <span class="n">f</span> <span class="p">);</span>
<span class="p">}</span>
<span class="p">}</span>
<span class="k">using</span> <span class="k">namespace</span> <span class="n">boost</span><span class="o">::</span><span class="n">mp11</span><span class="p">;</span>
<span class="k">using</span> <span class="k">namespace</span> <span class="n">boost</span><span class="o">::</span><span class="n">hash2</span><span class="p">;</span>
<span class="k">using</span> <span class="n">hashes</span> <span class="o">=</span> <span class="n">mp_list</span><span class="o">&lt;</span>
<span class="n">md5_128</span><span class="p">,</span>
<span class="n">sha1_160</span><span class="p">,</span>
<span class="n">sha2_256</span><span class="p">,</span>
<span class="n">sha2_224</span><span class="p">,</span>
<span class="n">sha2_512</span><span class="p">,</span>
<span class="n">sha2_384</span><span class="p">,</span>
<span class="n">sha2_512_256</span><span class="p">,</span>
<span class="n">sha2_512_224</span><span class="p">,</span>
<span class="n">ripemd_160</span><span class="p">,</span>
<span class="n">ripemd_128</span>
<span class="o">&gt;</span><span class="p">;</span>
<span class="k">constexpr</span> <span class="kt">char</span> <span class="k">const</span><span class="o">*</span> <span class="n">names</span><span class="p">[]</span> <span class="o">=</span> <span class="p">{</span>
<span class="s">"md5_128"</span><span class="p">,</span>
<span class="s">"sha1_160"</span><span class="p">,</span>
<span class="s">"sha2_256"</span><span class="p">,</span>
<span class="s">"sha2_224"</span><span class="p">,</span>
<span class="s">"sha2_512"</span><span class="p">,</span>
<span class="s">"sha2_384"</span><span class="p">,</span>
<span class="s">"sha2_512_256"</span><span class="p">,</span>
<span class="s">"sha2_512_224"</span><span class="p">,</span>
<span class="s">"ripemd_160"</span><span class="p">,</span>
<span class="s">"ripemd_128"</span>
<span class="p">};</span>
<span class="kt">int</span> <span class="n">main</span><span class="p">(</span> <span class="kt">int</span> <span class="n">argc</span><span class="p">,</span> <span class="kt">char</span> <span class="k">const</span><span class="o">*</span> <span class="n">argv</span><span class="p">[]</span> <span class="p">)</span>
<span class="p">{</span>
<span class="k">if</span><span class="p">(</span> <span class="n">argc</span> <span class="o">&lt;</span> <span class="mi">2</span> <span class="p">)</span>
<span class="p">{</span>
<span class="n">std</span><span class="o">::</span><span class="n">fputs</span><span class="p">(</span> <span class="s">"usage: hash2sum &lt;hash&gt; &lt;files...&gt;</span><span class="se">\n</span><span class="s">"</span><span class="p">,</span> <span class="n">stderr</span> <span class="p">);</span>
<span class="k">return</span> <span class="mi">2</span><span class="p">;</span>
<span class="p">}</span>
<span class="n">std</span><span class="o">::</span><span class="n">string</span> <span class="n">hash</span><span class="p">(</span> <span class="n">argv</span><span class="p">[</span><span class="mi">1</span><span class="p">]</span> <span class="p">);</span>
<span class="kt">bool</span> <span class="n">found</span> <span class="o">=</span> <span class="nb">false</span><span class="p">;</span>
<span class="n">mp_for_each</span><span class="o">&lt;</span> <span class="n">mp_iota</span><span class="o">&lt;</span><span class="n">mp_size</span><span class="o">&lt;</span><span class="n">hashes</span><span class="o">&gt;&gt;</span> <span class="o">&gt;</span><span class="p">([</span><span class="o">&amp;</span><span class="p">](</span><span class="k">auto</span> <span class="n">I</span><span class="p">){</span>
<span class="k">if</span><span class="p">(</span> <span class="n">hash</span> <span class="o">==</span> <span class="n">names</span><span class="p">[</span><span class="n">I</span><span class="p">]</span> <span class="p">)</span>
<span class="p">{</span>
<span class="k">using</span> <span class="n">Hash</span> <span class="o">=</span> <span class="n">mp_at_c</span><span class="o">&lt;</span><span class="n">hashes</span><span class="p">,</span> <span class="n">I</span><span class="o">&gt;</span><span class="p">;</span>
<span class="k">for</span><span class="p">(</span> <span class="kt">int</span> <span class="n">i</span> <span class="o">=</span> <span class="mi">2</span><span class="p">;</span> <span class="n">i</span> <span class="o">&lt;</span> <span class="n">argc</span><span class="p">;</span> <span class="o">++</span><span class="n">i</span> <span class="p">)</span>
<span class="p">{</span>
<span class="n">hash2sum</span><span class="o">&lt;</span><span class="n">Hash</span><span class="o">&gt;</span><span class="p">(</span> <span class="n">argv</span><span class="p">[</span><span class="n">i</span><span class="p">]</span> <span class="p">);</span>
<span class="p">}</span>
<span class="n">found</span> <span class="o">=</span> <span class="nb">true</span><span class="p">;</span>
<span class="p">}</span>
<span class="p">});</span>
<span class="k">if</span><span class="p">(</span> <span class="o">!</span><span class="n">found</span> <span class="p">)</span>
<span class="p">{</span>
<span class="n">std</span><span class="o">::</span><span class="n">fprintf</span><span class="p">(</span> <span class="n">stderr</span><span class="p">,</span> <span class="s">"hash2sum: unknown hash algorithm name '%s'; use one of the following:</span><span class="se">\n\n</span><span class="s">"</span><span class="p">,</span> <span class="n">hash</span><span class="p">.</span><span class="n">c_str</span><span class="p">()</span> <span class="p">);</span>
<span class="k">for</span><span class="p">(</span> <span class="kt">char</span> <span class="k">const</span><span class="o">*</span> <span class="n">name</span><span class="o">:</span> <span class="n">names</span> <span class="p">)</span>
<span class="p">{</span>
<span class="n">std</span><span class="o">::</span><span class="n">fprintf</span><span class="p">(</span> <span class="n">stderr</span><span class="p">,</span> <span class="s">" %s</span><span class="se">\n</span><span class="s">"</span><span class="p">,</span> <span class="n">name</span> <span class="p">);</span>
<span class="p">}</span>
<span class="k">return</span> <span class="mi">1</span><span class="p">;</span>
<span class="p">}</span>
<span class="p">}</span></code></pre>
</div>
</div>
<div class="paragraph">
<p>Sample command:</p>
</div>
<div class="listingblock">
<div class="content">
<pre>hash2sum sha2_512_224 apache_builds.json canada.json citm_catalog.json twitter.json</pre>
</div>
</div>
<div class="paragraph">
<p>Sample output:</p>
</div>
<div class="listingblock">
<div class="content">
<pre>a95d7fde785fe24f9507fd1709014567bbc595867f1abaad96f50dbc *apache_builds.json
b07e42587d10ec323a25fd8fc3eef2213fb0997beb7950350f4e8a4b *canada.json
4ceee5a83ad320fedb0dfddfb6f80af50b99677e87158e2d039aa168 *citm_catalog.json
854ebe0da98cadd426ea0fa3218d60bb52cf6494e435d2f385a37d48 *twitter.json</pre>
</div>
</div>
</div>
<div class="sect2">
<h3 id="example_compile_time_hashing">Compile Time Hashing</h3>
<div class="paragraph">
<p>This example demonstrates calculating the MD5 digest of a data array, embedded in the program source, at compile time. It requires C&#43;&#43;14.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="rouge highlight"><code data-lang="c++"><span class="cp">#include</span> <span class="cpf">&lt;boost/hash2/md5.hpp&gt;</span><span class="cp">
#include</span> <span class="cpf">&lt;iostream&gt;</span><span class="cp">
</span>
<span class="c1">// xxd -i resource</span>
<span class="k">constexpr</span> <span class="kt">unsigned</span> <span class="kt">char</span> <span class="n">resource</span><span class="p">[]</span> <span class="o">=</span> <span class="p">{</span>
<span class="mh">0x1f</span><span class="p">,</span> <span class="mh">0x8b</span><span class="p">,</span> <span class="mh">0x08</span><span class="p">,</span> <span class="mh">0x00</span><span class="p">,</span> <span class="mh">0x00</span><span class="p">,</span> <span class="mh">0x00</span><span class="p">,</span> <span class="mh">0x00</span><span class="p">,</span> <span class="mh">0x00</span><span class="p">,</span> <span class="mh">0x02</span><span class="p">,</span> <span class="mh">0x03</span><span class="p">,</span> <span class="mh">0x6d</span><span class="p">,</span> <span class="mh">0x90</span><span class="p">,</span>
<span class="mh">0xcf</span><span class="p">,</span> <span class="mh">0x6e</span><span class="p">,</span> <span class="mh">0x83</span><span class="p">,</span> <span class="mh">0x30</span><span class="p">,</span> <span class="mh">0x0c</span><span class="p">,</span> <span class="mh">0xc6</span><span class="p">,</span> <span class="mh">0xcf</span><span class="p">,</span> <span class="mh">0x45</span><span class="p">,</span> <span class="mh">0xea</span><span class="p">,</span> <span class="mh">0x3b</span><span class="p">,</span> <span class="mh">0x78</span><span class="p">,</span> <span class="mh">0x9c</span><span class="p">,</span>
<span class="mh">0x4b</span><span class="p">,</span> <span class="mh">0x02</span><span class="p">,</span> <span class="mh">0x3d</span><span class="p">,</span> <span class="mh">0x6e</span><span class="p">,</span> <span class="mh">0xd0</span><span class="p">,</span> <span class="mh">0x43</span><span class="p">,</span> <span class="mh">0xff</span><span class="p">,</span> <span class="mh">0x1c</span><span class="p">,</span> <span class="mh">0x26</span><span class="p">,</span> <span class="mh">0x55</span><span class="p">,</span> <span class="mh">0x3b</span><span class="p">,</span> <span class="mh">0x14</span><span class="p">,</span>
<span class="mh">0x6d</span><span class="p">,</span> <span class="mh">0xd7</span><span class="p">,</span> <span class="mh">0x2a</span><span class="p">,</span> <span class="mh">0x04</span><span class="p">,</span> <span class="mh">0x43</span><span class="p">,</span> <span class="mh">0x22</span><span class="p">,</span> <span class="mh">0x95</span><span class="p">,</span> <span class="mh">0x84</span><span class="p">,</span> <span class="mh">0x25</span><span class="p">,</span> <span class="mh">0x66</span><span class="p">,</span> <span class="mh">0x8c</span><span class="p">,</span> <span class="mh">0x47</span><span class="p">,</span>
<span class="mh">0xda</span><span class="p">,</span> <span class="mh">0x5b</span><span class="p">,</span> <span class="mh">0x2e</span><span class="p">,</span> <span class="mh">0x91</span><span class="p">,</span> <span class="mh">0xd6</span><span class="p">,</span> <span class="mh">0xcb</span><span class="p">,</span> <span class="mh">0xd4</span><span class="p">,</span> <span class="mh">0x93</span><span class="p">,</span> <span class="mh">0x2d</span><span class="p">,</span> <span class="mh">0xdb</span><span class="p">,</span> <span class="mh">0xdf</span><span class="p">,</span> <span class="mh">0xef</span><span class="p">,</span>
<span class="mh">0xb3</span><span class="p">,</span> <span class="mh">0x5d</span><span class="p">,</span> <span class="mh">0x2a</span><span class="p">,</span> <span class="mh">0x1a</span><span class="p">,</span> <span class="mh">0x6e</span><span class="p">,</span> <span class="mh">0xbb</span><span class="p">,</span> <span class="mh">0x75</span><span class="p">,</span> <span class="mh">0x52</span><span class="p">,</span> <span class="mh">0x2a</span><span class="p">,</span> <span class="mh">0x14</span><span class="p">,</span> <span class="mh">0x6d</span><span class="p">,</span> <span class="mh">0x8c</span><span class="p">,</span>
<span class="mh">0x03</span><span class="p">,</span> <span class="mh">0x92</span><span class="p">,</span> <span class="mh">0x00</span><span class="p">,</span> <span class="mh">0x45</span><span class="p">,</span> <span class="mh">0x34</span><span class="p">,</span> <span class="mh">0x66</span><span class="p">,</span> <span class="mh">0xf8</span><span class="p">,</span> <span class="mh">0x39</span><span class="p">,</span> <span class="mh">0xe9</span><span class="p">,</span> <span class="mh">0xaf</span><span class="p">,</span> <span class="mh">0x2a</span><span class="p">,</span> <span class="mh">0x75</span><span class="p">,</span>
<span class="mh">0xd8</span><span class="p">,</span> <span class="mh">0x39</span><span class="p">,</span> <span class="mh">0xf4</span><span class="p">,</span> <span class="mh">0x2a</span><span class="p">,</span> <span class="mh">0x05</span><span class="p">,</span> <span class="mh">0x69</span><span class="p">,</span> <span class="mh">0x0d</span><span class="p">,</span> <span class="mh">0xa1</span><span class="p">,</span> <span class="mh">0xa1</span><span class="p">,</span> <span class="mh">0x2a</span><span class="p">,</span> <span class="mh">0xcd</span><span class="p">,</span> <span class="mh">0x5f</span><span class="p">,</span>
<span class="mh">0xe0</span><span class="p">,</span> <span class="mh">0xfd</span><span class="p">,</span> <span class="mh">0x72</span><span class="p">,</span> <span class="mh">0xae</span><span class="p">,</span> <span class="mh">0x5a</span><span class="p">,</span> <span class="mh">0x2b</span><span class="p">,</span> <span class="mh">0x79</span><span class="p">,</span> <span class="mh">0x54</span><span class="p">,</span> <span class="mh">0x73</span><span class="p">,</span> <span class="mh">0x25</span><span class="p">,</span> <span class="mh">0xbc</span><span class="p">,</span> <span class="mh">0xda</span><span class="p">,</span>
<span class="mh">0xb2</span><span class="p">,</span> <span class="mh">0x98</span><span class="p">,</span> <span class="mh">0xa6</span><span class="p">,</span> <span class="mh">0x91</span><span class="p">,</span> <span class="mh">0xc0</span><span class="p">,</span> <span class="mh">0xef</span><span class="p">,</span> <span class="mh">0xa8</span><span class="p">,</span> <span class="mh">0xc6</span><span class="p">,</span> <span class="mh">0xb6</span><span class="p">,</span> <span class="mh">0x4b</span><span class="p">,</span> <span class="mh">0x88</span><span class="p">,</span> <span class="mh">0x17</span><span class="p">,</span>
<span class="mh">0x6c</span><span class="p">,</span> <span class="mh">0xb5</span><span class="p">,</span> <span class="mh">0x43</span><span class="p">,</span> <span class="mh">0x49</span><span class="p">,</span> <span class="mh">0xda</span><span class="p">,</span> <span class="mh">0xf4</span><span class="p">,</span> <span class="mh">0x40</span><span class="p">,</span> <span class="mh">0x16</span><span class="p">,</span> <span class="mh">0xca</span><span class="p">,</span> <span class="mh">0x80</span><span class="p">,</span> <span class="mh">0x0f</span><span class="p">,</span> <span class="mh">0xcc</span><span class="p">,</span>
<span class="mh">0x2a</span><span class="p">,</span> <span class="mh">0x7d</span><span class="p">,</span> <span class="mh">0xa8</span><span class="p">,</span> <span class="mh">0x7f</span><span class="p">,</span> <span class="mh">0x50</span><span class="p">,</span> <span class="mh">0x2c</span><span class="p">,</span> <span class="mh">0xb9</span><span class="p">,</span> <span class="mh">0xd8</span><span class="p">,</span> <span class="mh">0x31</span><span class="p">,</span> <span class="mh">0xc6</span><span class="p">,</span> <span class="mh">0x22</span><span class="p">,</span> <span class="mh">0xf9</span><span class="p">,</span>
<span class="mh">0x8f</span><span class="p">,</span> <span class="mh">0x58</span><span class="p">,</span> <span class="mh">0xf2</span><span class="p">,</span> <span class="mh">0xfb</span><span class="p">,</span> <span class="mh">0xd6</span><span class="p">,</span> <span class="mh">0x4f</span><span class="p">,</span> <span class="mh">0x59</span><span class="p">,</span> <span class="mh">0xb6</span><span class="p">,</span> <span class="mh">0x4e</span><span class="p">,</span> <span class="mh">0x56</span><span class="p">,</span> <span class="mh">0x3f</span><span class="p">,</span> <span class="mh">0x70</span><span class="p">,</span>
<span class="mh">0xb0</span><span class="p">,</span> <span class="mh">0xe3</span><span class="p">,</span> <span class="mh">0xe2</span><span class="p">,</span> <span class="mh">0x74</span><span class="p">,</span> <span class="mh">0xaf</span><span class="p">,</span> <span class="mh">0x08</span><span class="p">,</span> <span class="mh">0xf6</span><span class="p">,</span> <span class="mh">0x38</span><span class="p">,</span> <span class="mh">0x08</span><span class="p">,</span> <span class="mh">0x03</span><span class="p">,</span> <span class="mh">0x47</span><span class="p">,</span> <span class="mh">0x31</span><span class="p">,</span>
<span class="mh">0xa3</span><span class="p">,</span> <span class="mh">0xdf</span><span class="p">,</span> <span class="mh">0xc0</span><span class="p">,</span> <span class="mh">0x36</span><span class="p">,</span> <span class="mh">0xcf</span><span class="p">,</span> <span class="mh">0x8b</span><span class="p">,</span> <span class="mh">0xd0</span><span class="p">,</span> <span class="mh">0x3f</span><span class="p">,</span> <span class="mh">0x6a</span><span class="p">,</span> <span class="mh">0x4f</span><span class="p">,</span> <span class="mh">0x4e</span><span class="p">,</span> <span class="mh">0x37</span><span class="p">,</span>
<span class="mh">0x13</span><span class="p">,</span> <span class="mh">0x61</span><span class="p">,</span> <span class="mh">0x0b</span><span class="p">,</span> <span class="mh">0x93</span><span class="p">,</span> <span class="mh">0x69</span><span class="p">,</span> <span class="mh">0xd1</span><span class="p">,</span> <span class="mh">0x01</span><span class="p">,</span> <span class="mh">0x29</span><span class="p">,</span> <span class="mh">0x84</span><span class="p">,</span> <span class="mh">0xbd</span><span class="p">,</span> <span class="mh">0xb5</span><span class="p">,</span> <span class="mh">0x9e</span><span class="p">,</span>
<span class="mh">0xa0</span><span class="p">,</span> <span class="mh">0xb6</span><span class="p">,</span> <span class="mh">0x1d</span><span class="p">,</span> <span class="mh">0xcd</span><span class="p">,</span> <span class="mh">0xc2</span><span class="p">,</span> <span class="mh">0x21</span><span class="p">,</span> <span class="mh">0x9c</span><span class="p">,</span> <span class="mh">0xb5</span><span class="p">,</span> <span class="mh">0x44</span><span class="p">,</span> <span class="mh">0xe3</span><span class="p">,</span> <span class="mh">0x71</span><span class="p">,</span> <span class="mh">0x03</span><span class="p">,</span>
<span class="mh">0x1f</span><span class="p">,</span> <span class="mh">0xe8</span><span class="p">,</span> <span class="mh">0xbc</span><span class="p">,</span> <span class="mh">0xb6</span><span class="p">,</span> <span class="mh">0x06</span><span class="p">,</span> <span class="mh">0x0a</span><span class="p">,</span> <span class="mh">0x96</span><span class="p">,</span> <span class="mh">0x07</span><span class="p">,</span> <span class="mh">0xd3</span><span class="p">,</span> <span class="mh">0x55</span><span class="p">,</span> <span class="mh">0x8d</span><span class="p">,</span> <span class="mh">0x08</span><span class="p">,</span>
<span class="mh">0x42</span><span class="p">,</span> <span class="mh">0x4a</span><span class="p">,</span> <span class="mh">0x3b</span><span class="p">,</span> <span class="mh">0x8c</span><span class="p">,</span> <span class="mh">0xc2</span><span class="p">,</span> <span class="mh">0x2c</span><span class="p">,</span> <span class="mh">0xf1</span><span class="p">,</span> <span class="mh">0x86</span><span class="p">,</span> <span class="mh">0x4e</span><span class="p">,</span> <span class="mh">0xdf</span><span class="p">,</span> <span class="mh">0xc2</span><span class="p">,</span> <span class="mh">0xf4</span><span class="p">,</span>
<span class="mh">0xeb</span><span class="p">,</span> <span class="mh">0xe1</span><span class="p">,</span> <span class="mh">0xf4</span><span class="p">,</span> <span class="mh">0x56</span><span class="p">,</span> <span class="mh">0x9f</span><span class="p">,</span> <span class="mh">0xae</span><span class="p">,</span> <span class="mh">0xc5</span><span class="p">,</span> <span class="mh">0x35</span><span class="p">,</span> <span class="mh">0x67</span><span class="p">,</span> <span class="mh">0xf4</span><span class="p">,</span> <span class="mh">0x4d</span><span class="p">,</span> <span class="mh">0x60</span><span class="p">,</span>
<span class="mh">0x5d</span><span class="p">,</span> <span class="mh">0xf8</span><span class="p">,</span> <span class="mh">0xcf</span><span class="p">,</span> <span class="mh">0xb8</span><span class="p">,</span> <span class="mh">0x80</span><span class="p">,</span> <span class="mh">0xa0</span><span class="p">,</span> <span class="mh">0x20</span><span class="p">,</span> <span class="mh">0x89</span><span class="p">,</span> <span class="mh">0xef</span><span class="p">,</span> <span class="mh">0x7b</span><span class="p">,</span> <span class="mh">0xe6</span><span class="p">,</span> <span class="mh">0x7c</span><span class="p">,</span>
<span class="mh">0x9e</span><span class="p">,</span> <span class="mh">0x67</span><span class="p">,</span> <span class="mh">0xd6</span><span class="p">,</span> <span class="mh">0x44</span><span class="p">,</span> <span class="mh">0x13</span><span class="p">,</span> <span class="mh">0x66</span><span class="p">,</span> <span class="mh">0x5d</span><span class="p">,</span> <span class="mh">0xcf</span><span class="p">,</span> <span class="mh">0xff</span><span class="p">,</span> <span class="mh">0x29</span><span class="p">,</span> <span class="mh">0xd6</span><span class="p">,</span> <span class="mh">0x49</span><span class="p">,</span>
<span class="mh">0x96</span><span class="p">,</span> <span class="mh">0x85</span><span class="p">,</span> <span class="mh">0x0b</span><span class="p">,</span> <span class="mh">0x7e</span><span class="p">,</span> <span class="mh">0x01</span><span class="p">,</span> <span class="mh">0x36</span><span class="p">,</span> <span class="mh">0x66</span><span class="p">,</span> <span class="mh">0x95</span><span class="p">,</span> <span class="mh">0x6b</span><span class="p">,</span> <span class="mh">0x80</span><span class="p">,</span> <span class="mh">0x01</span><span class="p">,</span> <span class="mh">0x00</span><span class="p">,</span>
<span class="mh">0x00</span>
<span class="p">};</span>
<span class="k">template</span><span class="o">&lt;</span><span class="n">std</span><span class="o">::</span><span class="kt">size_t</span> <span class="n">N</span><span class="p">&gt;</span> <span class="k">constexpr</span> <span class="k">auto</span> <span class="n">md5</span><span class="p">(</span> <span class="kt">unsigned</span> <span class="kt">char</span> <span class="k">const</span><span class="p">(</span><span class="o">&amp;</span><span class="n">a</span><span class="p">)[</span> <span class="n">N</span> <span class="p">]</span> <span class="p">)</span>
<span class="p">{</span>
<span class="n">boost</span><span class="o">::</span><span class="n">hash2</span><span class="o">::</span><span class="n">md5_128</span> <span class="n">hash</span><span class="p">;</span>
<span class="n">hash</span><span class="p">.</span><span class="n">update</span><span class="p">(</span> <span class="n">a</span><span class="p">,</span> <span class="n">N</span> <span class="p">);</span>
<span class="k">return</span> <span class="n">hash</span><span class="p">.</span><span class="n">result</span><span class="p">();</span>
<span class="p">}</span>
<span class="k">constexpr</span> <span class="k">auto</span> <span class="n">resource_digest</span> <span class="o">=</span> <span class="n">md5</span><span class="p">(</span> <span class="n">resource</span> <span class="p">);</span>
<span class="kt">int</span> <span class="n">main</span><span class="p">()</span>
<span class="p">{</span>
<span class="n">std</span><span class="o">::</span><span class="n">cout</span> <span class="o">&lt;&lt;</span> <span class="s">"Resource digest: "</span> <span class="o">&lt;&lt;</span> <span class="n">resource_digest</span> <span class="o">&lt;&lt;</span> <span class="n">std</span><span class="o">::</span><span class="n">endl</span><span class="p">;</span>
<span class="p">}</span></code></pre>
</div>
</div>
<div class="paragraph">
<p>Since the <code>constexpr</code> overload of <code>update</code> takes <code>unsigned char const*</code> (<code>void const*</code> is not allowed in <code>constexpr</code> functions), if the
data to be hashed is a character array of type <code>char const[]</code>, passing it directly to <code>update</code> will not compile. In that case, we can
use <code>hash_append_range</code> instead of calling <code>update</code>, as in the following example.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="rouge highlight"><code data-lang="c++"><span class="cp">#include</span> <span class="cpf">&lt;boost/hash2/sha2.hpp&gt;</span><span class="cp">
#include</span> <span class="cpf">&lt;boost/hash2/hash_append.hpp&gt;</span><span class="cp">
#include</span> <span class="cpf">&lt;iostream&gt;</span><span class="cp">
</span>
<span class="k">extern</span> <span class="k">constexpr</span> <span class="kt">char</span> <span class="k">const</span> <span class="n">license</span><span class="p">[]</span> <span class="o">=</span>
<span class="s">"Boost Software License - Version 1.0 - August 17th, 2003</span><span class="se">\n</span><span class="s">"</span>
<span class="s">"</span><span class="se">\n</span><span class="s">"</span>
<span class="s">"Permission is hereby granted, free of charge, to any person or organization</span><span class="se">\n</span><span class="s">"</span>
<span class="s">"obtaining a copy of the software and accompanying documentation covered by</span><span class="se">\n</span><span class="s">"</span>
<span class="s">"this license (the </span><span class="se">\"</span><span class="s">Software</span><span class="se">\"</span><span class="s">) to use, reproduce, display, distribute,</span><span class="se">\n</span><span class="s">"</span>
<span class="s">"execute, and transmit the Software, and to prepare derivative works of the</span><span class="se">\n</span><span class="s">"</span>
<span class="s">"Software, and to permit third-parties to whom the Software is furnished to</span><span class="se">\n</span><span class="s">"</span>
<span class="s">"do so, all subject to the following:</span><span class="se">\n</span><span class="s">"</span>
<span class="s">"</span><span class="se">\n</span><span class="s">"</span>
<span class="s">"The copyright notices in the Software and this entire statement, including</span><span class="se">\n</span><span class="s">"</span>
<span class="s">"the above license grant, this restriction and the following disclaimer,</span><span class="se">\n</span><span class="s">"</span>
<span class="s">"must be included in all copies of the Software, in whole or in part, and</span><span class="se">\n</span><span class="s">"</span>
<span class="s">"all derivative works of the Software, unless such copies or derivative</span><span class="se">\n</span><span class="s">"</span>
<span class="s">"works are solely in the form of machine-executable object code generated by</span><span class="se">\n</span><span class="s">"</span>
<span class="s">"a source language processor.</span><span class="se">\n</span><span class="s">"</span>
<span class="s">"</span><span class="se">\n</span><span class="s">"</span>
<span class="s">"THE SOFTWARE IS PROVIDED </span><span class="se">\"</span><span class="s">AS IS</span><span class="se">\"</span><span class="s">, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR</span><span class="se">\n</span><span class="s">"</span>
<span class="s">"IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,</span><span class="se">\n</span><span class="s">"</span>
<span class="s">"FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT</span><span class="se">\n</span><span class="s">"</span>
<span class="s">"SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE</span><span class="se">\n</span><span class="s">"</span>
<span class="s">"FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,</span><span class="se">\n</span><span class="s">"</span>
<span class="s">"ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER</span><span class="se">\n</span><span class="s">"</span>
<span class="s">"DEALINGS IN THE SOFTWARE.</span><span class="se">\n</span><span class="s">"</span>
<span class="p">;</span>
<span class="k">constexpr</span> <span class="kt">unsigned</span> <span class="kt">char</span> <span class="n">secret</span><span class="p">[]</span> <span class="o">=</span> <span class="p">{</span>
<span class="mh">0xA4</span><span class="p">,</span> <span class="mh">0x80</span><span class="p">,</span> <span class="mh">0x0E</span><span class="p">,</span> <span class="mh">0xE8</span><span class="p">,</span> <span class="mh">0x20</span><span class="p">,</span> <span class="mh">0x0B</span><span class="p">,</span> <span class="mh">0x7C</span><span class="p">,</span> <span class="mh">0x9A</span><span class="p">,</span>
<span class="mh">0xF1</span><span class="p">,</span> <span class="mh">0x3E</span><span class="p">,</span> <span class="mh">0x3D</span><span class="p">,</span> <span class="mh">0xEC</span><span class="p">,</span> <span class="mh">0x64</span><span class="p">,</span> <span class="mh">0x4F</span><span class="p">,</span> <span class="mh">0x64</span><span class="p">,</span> <span class="mh">0xCA</span><span class="p">,</span>
<span class="mh">0x33</span><span class="p">,</span> <span class="mh">0xCC</span><span class="p">,</span> <span class="mh">0x84</span><span class="p">,</span> <span class="mh">0xC8</span><span class="p">,</span> <span class="mh">0x34</span><span class="p">,</span> <span class="mh">0xE3</span><span class="p">,</span> <span class="mh">0x08</span><span class="p">,</span> <span class="mh">0xAE</span><span class="p">,</span>
<span class="mh">0x92</span><span class="p">,</span> <span class="mh">0x89</span><span class="p">,</span> <span class="mh">0xEB</span><span class="p">,</span> <span class="mh">0xD0</span><span class="p">,</span> <span class="mh">0x47</span><span class="p">,</span> <span class="mh">0x39</span><span class="p">,</span> <span class="mh">0x87</span><span class="p">,</span> <span class="mh">0xD8</span><span class="p">,</span>
<span class="p">};</span>
<span class="k">template</span><span class="o">&lt;</span><span class="n">std</span><span class="o">::</span><span class="kt">size_t</span> <span class="n">N</span><span class="p">&gt;</span> <span class="k">constexpr</span> <span class="k">auto</span> <span class="n">hmac_sha2_256</span><span class="p">(</span> <span class="kt">char</span> <span class="k">const</span><span class="p">(</span><span class="o">&amp;</span><span class="n">s</span><span class="p">)[</span> <span class="n">N</span> <span class="p">]</span> <span class="p">)</span>
<span class="p">{</span>
<span class="n">boost</span><span class="o">::</span><span class="n">hash2</span><span class="o">::</span><span class="n">hmac_sha2_256</span> <span class="n">hmac</span><span class="p">(</span> <span class="n">secret</span><span class="p">,</span> <span class="k">sizeof</span><span class="p">(</span><span class="n">secret</span><span class="p">)</span> <span class="p">);</span>
<span class="c1">// N-1, in order to not include the null terminator</span>
<span class="n">boost</span><span class="o">::</span><span class="n">hash2</span><span class="o">::</span><span class="n">hash_append_range</span><span class="p">(</span> <span class="n">hmac</span><span class="p">,</span> <span class="p">{},</span> <span class="n">s</span><span class="p">,</span> <span class="n">s</span> <span class="o">+</span> <span class="n">N</span> <span class="o">-</span> <span class="mi">1</span> <span class="p">);</span>
<span class="k">return</span> <span class="n">hmac</span><span class="p">.</span><span class="n">result</span><span class="p">();</span>
<span class="p">}</span>
<span class="k">constexpr</span> <span class="k">auto</span> <span class="n">license_mac</span> <span class="o">=</span> <span class="n">hmac_sha2_256</span><span class="p">(</span> <span class="n">license</span> <span class="p">);</span>
<span class="kt">int</span> <span class="n">main</span><span class="p">()</span>
<span class="p">{</span>
<span class="n">std</span><span class="o">::</span><span class="n">cout</span> <span class="o">&lt;&lt;</span> <span class="s">"License authentication code: "</span> <span class="o">&lt;&lt;</span> <span class="n">license_mac</span> <span class="o">&lt;&lt;</span> <span class="n">std</span><span class="o">::</span><span class="n">endl</span><span class="p">;</span>
<span class="p">}</span></code></pre>
</div>
</div>
</div>
</div>
</div>
<div class="sect1">
<h2 id="implementation">Implementation Features</h2>
<div class="sectionbody">
<div class="sect2">
<h3 id="implementation_supported_compilers">Supported Compilers</h3>
<div class="paragraph">
<p>The library requires C&#43;&#43;11. The following compilers:</p>
</div>
<div class="ulist">
<ul>
<li>
<p>g++ 4.8 or later</p>
</li>
<li>
<p>clang++ 3.9 or later</p>
</li>
<li>
<p>Visual Studio 2015 and above</p>
</li>
</ul>
</div>
<div class="paragraph">
<p>are being tested on <a href="https://github.com/pdimov/hash2/actions/">Github Actions</a>
and <a href="https://ci.appveyor.com/project/pdimov/hash2/">Appveyor</a>.</p>
</div>
</div>
</div>
</div>
<div class="sect1">
<h2 id="reference">Reference</h2>
<div class="sectionbody">
<div class="sect2">
<h3 id="ref_hash_algorithms">Hash Algorithms</h3>
<div class="sect3">
<h4 id="ref_fnv1a">&lt;boost/hash2/fnv1a.hpp&gt;</h4>
<div class="listingblock">
<div class="content">
<pre class="rouge highlight"><code data-lang="c++"><span class="k">namespace</span> <span class="n">boost</span> <span class="p">{</span>
<span class="k">namespace</span> <span class="n">hash2</span> <span class="p">{</span>
<span class="k">class</span> <span class="nc">fnv1a_32</span><span class="p">;</span>
<span class="k">class</span> <span class="nc">fnv1a_64</span><span class="p">;</span>
<span class="p">}</span> <span class="c1">// namespace hash2</span>
<span class="p">}</span> <span class="c1">// namespace boost</span></code></pre>
</div>
</div>
<div class="paragraph">
<p>This header implements the <a href="https://en.wikipedia.org/wiki/Fowler%E2%80%93Noll%E2%80%93Vo_hash_function">FNV-1a algorithm</a>, in 32 and 64 bit variants.</p>
</div>
<div class="sect4">
<h5 id="ref_fnv1a_fnv1a_32">fnv1a_32</h5>
<div class="listingblock">
<div class="content">
<pre class="rouge highlight"><code data-lang="c++"><span class="k">class</span> <span class="nc">fnv1a_32</span>
<span class="p">{</span>
<span class="nl">private:</span>
<span class="n">std</span><span class="o">::</span><span class="kt">uint32_t</span> <span class="n">state_</span><span class="p">;</span> <span class="c1">// exposition only</span>
<span class="nl">public:</span>
<span class="k">using</span> <span class="n">result_type</span> <span class="o">=</span> <span class="n">std</span><span class="o">::</span><span class="kt">uint32_t</span><span class="p">;</span>
<span class="k">constexpr</span> <span class="n">fnv1a_32</span><span class="p">();</span>
<span class="k">explicit</span> <span class="k">constexpr</span> <span class="n">fnv1a_32</span><span class="p">(</span> <span class="n">std</span><span class="o">::</span><span class="kt">uint64_t</span> <span class="n">seed</span> <span class="p">);</span>
<span class="k">constexpr</span> <span class="n">fnv1a_32</span><span class="p">(</span> <span class="kt">unsigned</span> <span class="kt">char</span> <span class="k">const</span><span class="o">*</span> <span class="n">p</span><span class="p">,</span> <span class="n">std</span><span class="o">::</span><span class="kt">size_t</span> <span class="n">n</span> <span class="p">);</span>
<span class="kt">void</span> <span class="n">update</span><span class="p">(</span> <span class="kt">void</span> <span class="k">const</span><span class="o">*</span> <span class="n">p</span><span class="p">,</span> <span class="n">std</span><span class="o">::</span><span class="kt">size_t</span> <span class="n">n</span> <span class="p">);</span>
<span class="k">constexpr</span> <span class="kt">void</span> <span class="n">update</span><span class="p">(</span> <span class="kt">unsigned</span> <span class="kt">char</span> <span class="k">const</span><span class="o">*</span> <span class="n">p</span><span class="p">,</span> <span class="n">std</span><span class="o">::</span><span class="kt">size_t</span> <span class="n">n</span> <span class="p">);</span>
<span class="k">constexpr</span> <span class="n">result_type</span> <span class="n">result</span><span class="p">();</span>
<span class="p">};</span></code></pre>
</div>
</div>
<div class="sect5">
<h6 id="ref_fnv1a_constructors">Constructors</h6>
<div class="listingblock">
<div class="content">
<pre class="rouge highlight"><code data-lang="c++"><span class="k">constexpr</span> <span class="nf">fnv1a_32</span><span class="p">();</span></code></pre>
</div>
</div>
<div class="paragraph">
<p>Default constructor.</p>
</div>
<div class="dlist">
<dl>
<dt class="hdlist1">Effects: </dt>
<dd>
<p>Initializes <code>state_</code> to <code>0x811c9dc5</code>.</p>
</dd>
</dl>
</div>
<div class="listingblock">
<div class="content">
<pre class="rouge highlight"><code data-lang="c++"><span class="k">explicit</span> <span class="k">constexpr</span> <span class="nf">fnv1a_32</span><span class="p">(</span> <span class="n">std</span><span class="o">::</span><span class="kt">uint64_t</span> <span class="n">seed</span> <span class="p">);</span></code></pre>
</div>
</div>
<div class="paragraph">
<p>Constructor taking an integer seed value.</p>
</div>
<div class="dlist">
<dl>
<dt class="hdlist1">Effects: </dt>
<dd>
<p>Initializes the state as if by default construction, then if <code>seed</code> is not zero, performs <code>update(p, 8)</code> where <code>p</code> points to a little-endian representation of the value of <code>seed</code>.</p>
</dd>
<dt class="hdlist1">Remarks: </dt>
<dd>
<p>By convention, if <code>seed</code> is zero, the effect of this constructor is the same as default construction.</p>
</dd>
</dl>
</div>
<div class="listingblock">
<div class="content">
<pre class="rouge highlight"><code data-lang="c++"><span class="k">constexpr</span> <span class="nf">fnv1a_32</span><span class="p">(</span> <span class="kt">unsigned</span> <span class="kt">char</span> <span class="k">const</span><span class="o">*</span> <span class="n">p</span><span class="p">,</span> <span class="n">std</span><span class="o">::</span><span class="kt">size_t</span> <span class="n">n</span> <span class="p">);</span></code></pre>
</div>
</div>
<div class="paragraph">
<p>Constructor taking a byte sequence seed.</p>
</div>
<div class="dlist">
<dl>
<dt class="hdlist1">Effects: </dt>
<dd>
<p>Initializes the state as if by default construction, and then, if <code>n</code> is not zero, performs <code>update(p, n)</code>.</p>
</dd>
<dt class="hdlist1">Remarks: </dt>
<dd>
<p>By convention, if <code>n</code> is zero, the effect of this constructor is the same as default construction.</p>
</dd>
</dl>
</div>
</div>
<div class="sect5">
<h6 id="ref_fnv1a_update">update</h6>
<div class="listingblock">
<div class="content">
<pre class="rouge highlight"><code data-lang="c++"><span class="kt">void</span> <span class="nf">update</span><span class="p">(</span> <span class="kt">void</span> <span class="k">const</span><span class="o">*</span> <span class="n">p</span><span class="p">,</span> <span class="n">std</span><span class="o">::</span><span class="kt">size_t</span> <span class="n">n</span> <span class="p">);</span>
<span class="k">constexpr</span> <span class="kt">void</span> <span class="nf">update</span><span class="p">(</span> <span class="kt">unsigned</span> <span class="kt">char</span> <span class="k">const</span><span class="o">*</span> <span class="n">p</span><span class="p">,</span> <span class="n">std</span><span class="o">::</span><span class="kt">size_t</span> <span class="n">n</span> <span class="p">);</span></code></pre>
</div>
</div>
<div class="dlist">
<dl>
<dt class="hdlist1">Effects: </dt>
<dd>
<p>For each <code>unsigned char</code> value <code>ch</code> in the range <code>[p, p+n)</code> performs <code>state_ = (state_ ^ ch) * 0x01000193</code>.</p>
</dd>
</dl>
</div>
</div>
<div class="sect5">
<h6 id="ref_fnv1a_result">result</h6>
<div class="listingblock">
<div class="content">
<pre class="rouge highlight"><code data-lang="c++"><span class="k">constexpr</span> <span class="n">result_type</span> <span class="nf">result</span><span class="p">();</span></code></pre>
</div>
</div>
<div class="dlist">
<dl>
<dt class="hdlist1">Effects: </dt>
<dd>
<p>Updates <code>state_</code> to <code>(state_ ^ 0xFF) * 0x01000193</code>.</p>
</dd>
<dt class="hdlist1">Returns: </dt>
<dd>
<p>The value of <code>state_</code> before the update.</p>
</dd>
<dt class="hdlist1">Remarks: </dt>
<dd>
<p>The state is updated to allow repeated calls to <code>result()</code> to return
a pseudorandom sequence of <code>result_type</code> values, effectively extending
the output.</p>
</dd>
</dl>
</div>
</div>
</div>
<div class="sect4">
<h5 id="ref_fnv1a_fnv1a_64">fnv1a_64</h5>
<div class="listingblock">
<div class="content">
<pre class="rouge highlight"><code data-lang="c++"><span class="k">class</span> <span class="nc">fnv1a_64</span>
<span class="p">{</span>
<span class="nl">private:</span>
<span class="n">std</span><span class="o">::</span><span class="kt">uint64_t</span> <span class="n">state_</span><span class="p">;</span> <span class="c1">// exposition only</span>
<span class="nl">public:</span>
<span class="k">using</span> <span class="n">result_type</span> <span class="o">=</span> <span class="n">std</span><span class="o">::</span><span class="kt">uint64_t</span><span class="p">;</span>
<span class="k">constexpr</span> <span class="n">fnv1a_64</span><span class="p">();</span>
<span class="k">explicit</span> <span class="k">constexpr</span> <span class="n">fnv1a_64</span><span class="p">(</span> <span class="n">std</span><span class="o">::</span><span class="kt">uint64_t</span> <span class="n">seed</span> <span class="p">);</span>
<span class="k">constexpr</span> <span class="n">fnv1a_64</span><span class="p">(</span> <span class="kt">unsigned</span> <span class="kt">char</span> <span class="k">const</span><span class="o">*</span> <span class="n">p</span><span class="p">,</span> <span class="n">std</span><span class="o">::</span><span class="kt">size_t</span> <span class="n">n</span> <span class="p">);</span>
<span class="kt">void</span> <span class="n">update</span><span class="p">(</span> <span class="kt">void</span> <span class="k">const</span><span class="o">*</span> <span class="n">p</span><span class="p">,</span> <span class="n">std</span><span class="o">::</span><span class="kt">size_t</span> <span class="n">n</span> <span class="p">);</span>
<span class="k">constexpr</span> <span class="kt">void</span> <span class="n">update</span><span class="p">(</span> <span class="kt">unsigned</span> <span class="kt">char</span> <span class="k">const</span><span class="o">*</span> <span class="n">p</span><span class="p">,</span> <span class="n">std</span><span class="o">::</span><span class="kt">size_t</span> <span class="n">n</span> <span class="p">);</span>
<span class="k">constexpr</span> <span class="n">result_type</span> <span class="n">result</span><span class="p">();</span>
<span class="p">};</span></code></pre>
</div>
</div>
<div class="sect5">
<h6 id="ref_fnv1a_constructors_2">Constructors</h6>
<div class="listingblock">
<div class="content">
<pre class="rouge highlight"><code data-lang="c++"><span class="k">constexpr</span> <span class="nf">fnv1a_64</span><span class="p">();</span></code></pre>
</div>
</div>
<div class="paragraph">
<p>Default constructor.</p>
</div>
<div class="dlist">
<dl>
<dt class="hdlist1">Effects: </dt>
<dd>
<p>Initializes <code>state_</code> to <code>0xcbf29ce484222325</code>.</p>
</dd>
</dl>
</div>
<div class="listingblock">
<div class="content">
<pre class="rouge highlight"><code data-lang="c++"><span class="k">explicit</span> <span class="k">constexpr</span> <span class="nf">fnv1a_64</span><span class="p">(</span> <span class="n">std</span><span class="o">::</span><span class="kt">uint64_t</span> <span class="n">seed</span> <span class="p">);</span></code></pre>
</div>
</div>
<div class="paragraph">
<p>Constructor taking an integer seed value.</p>
</div>
<div class="dlist">
<dl>
<dt class="hdlist1">Effects: </dt>
<dd>
<p>Initializes the state as if by default construction, then if <code>seed</code> is not zero, performs <code>update(p, 8)</code> where <code>p</code> points to a little-endian representation of the value of <code>seed</code>.</p>
</dd>
<dt class="hdlist1">Remarks: </dt>
<dd>
<p>By convention, if <code>seed</code> is zero, the effect of this constructor is the same as default construction.</p>
</dd>
</dl>
</div>
<div class="listingblock">
<div class="content">
<pre class="rouge highlight"><code data-lang="c++"><span class="k">constexpr</span> <span class="nf">fnv1a_64</span><span class="p">(</span> <span class="kt">unsigned</span> <span class="kt">char</span> <span class="k">const</span><span class="o">*</span> <span class="n">p</span><span class="p">,</span> <span class="n">std</span><span class="o">::</span><span class="kt">size_t</span> <span class="n">n</span> <span class="p">);</span></code></pre>
</div>
</div>
<div class="paragraph">
<p>Constructor taking a byte sequence seed.</p>
</div>
<div class="dlist">
<dl>
<dt class="hdlist1">Effects: </dt>
<dd>
<p>Initializes the state as if by default construction, and then, if <code>n</code> is not zero, performs <code>update(p, n)</code>.</p>
</dd>
<dt class="hdlist1">Remarks: </dt>
<dd>
<p>By convention, if <code>n</code> is zero, the effect of this constructor is the same as default construction.</p>
</dd>
</dl>
</div>
</div>
<div class="sect5">
<h6 id="ref_fnv1a_update_2">update</h6>
<div class="listingblock">
<div class="content">
<pre class="rouge highlight"><code data-lang="c++"><span class="kt">void</span> <span class="nf">update</span><span class="p">(</span> <span class="kt">void</span> <span class="k">const</span><span class="o">*</span> <span class="n">p</span><span class="p">,</span> <span class="n">std</span><span class="o">::</span><span class="kt">size_t</span> <span class="n">n</span> <span class="p">);</span>
<span class="k">constexpr</span> <span class="kt">void</span> <span class="nf">update</span><span class="p">(</span> <span class="kt">unsigned</span> <span class="kt">char</span> <span class="k">const</span><span class="o">*</span> <span class="n">p</span><span class="p">,</span> <span class="n">std</span><span class="o">::</span><span class="kt">size_t</span> <span class="n">n</span> <span class="p">);</span></code></pre>
</div>
</div>
<div class="dlist">
<dl>
<dt class="hdlist1">Effects: </dt>
<dd>
<p>For each <code>unsigned char</code> value <code>ch</code> in the range <code>[p, p+n)</code> performs <code>state_ = (state_ ^ ch) * 0x100000001b3</code>.</p>
</dd>
</dl>
</div>
</div>
<div class="sect5">
<h6 id="ref_fnv1a_result_2">result</h6>
<div class="listingblock">
<div class="content">
<pre class="rouge highlight"><code data-lang="c++"><span class="k">constexpr</span> <span class="n">result_type</span> <span class="nf">result</span><span class="p">();</span></code></pre>
</div>
</div>
<div class="dlist">
<dl>
<dt class="hdlist1">Effects: </dt>
<dd>
<p>Updates <code>state_</code> to <code>(state_ ^ 0xFF) * 0x100000001b3</code>.</p>
</dd>
<dt class="hdlist1">Returns: </dt>
<dd>
<p>The value of <code>state_</code> before the update.</p>
</dd>
<dt class="hdlist1">Remarks: </dt>
<dd>
<p>The state is updated to allow repeated calls to <code>result()</code> to return
a pseudorandom sequence of <code>result_type</code> values, effectively extending
the output.</p>
</dd>
</dl>
</div>
</div>
</div>
</div>
<div class="sect3">
<h4 id="ref_xxhash">&lt;boost/hash2/xxhash.hpp&gt;</h4>
<div class="listingblock">
<div class="content">
<pre class="rouge highlight"><code data-lang="c++"><span class="k">namespace</span> <span class="n">boost</span> <span class="p">{</span>
<span class="k">namespace</span> <span class="n">hash2</span> <span class="p">{</span>
<span class="k">class</span> <span class="nc">xxhash_32</span><span class="p">;</span>
<span class="k">class</span> <span class="nc">xxhash_64</span><span class="p">;</span>
<span class="p">}</span> <span class="c1">// namespace hash2</span>
<span class="p">}</span> <span class="c1">// namespace boost</span></code></pre>
</div>
</div>
<div class="paragraph">
<p>This header implements the <a href="https://xxhash.com/">XXH32 and XXH64 algorithms</a>.</p>
</div>
<div class="sect4">
<h5 id="ref_xxhash_xxhash_32">xxhash_32</h5>
<div class="listingblock">
<div class="content">
<pre class="rouge highlight"><code data-lang="c++"><span class="k">class</span> <span class="nc">xxhash_32</span>
<span class="p">{</span>
<span class="nl">public:</span>
<span class="k">using</span> <span class="n">result_type</span> <span class="o">=</span> <span class="n">std</span><span class="o">::</span><span class="kt">uint32_t</span><span class="p">;</span>
<span class="k">constexpr</span> <span class="n">xxhash_32</span><span class="p">();</span>
<span class="k">explicit</span> <span class="k">constexpr</span> <span class="n">xxhash_32</span><span class="p">(</span> <span class="n">std</span><span class="o">::</span><span class="kt">uint64_t</span> <span class="n">seed</span> <span class="p">);</span>
<span class="k">constexpr</span> <span class="n">xxhash_32</span><span class="p">(</span> <span class="kt">unsigned</span> <span class="kt">char</span> <span class="k">const</span><span class="o">*</span> <span class="n">p</span><span class="p">,</span> <span class="n">std</span><span class="o">::</span><span class="kt">size_t</span> <span class="n">n</span> <span class="p">);</span>
<span class="kt">void</span> <span class="n">update</span><span class="p">(</span> <span class="kt">void</span> <span class="k">const</span><span class="o">*</span> <span class="n">p</span><span class="p">,</span> <span class="n">std</span><span class="o">::</span><span class="kt">size_t</span> <span class="n">n</span> <span class="p">);</span>
<span class="k">constexpr</span> <span class="kt">void</span> <span class="n">update</span><span class="p">(</span> <span class="kt">unsigned</span> <span class="kt">char</span> <span class="k">const</span><span class="o">*</span> <span class="n">p</span><span class="p">,</span> <span class="n">std</span><span class="o">::</span><span class="kt">size_t</span> <span class="n">n</span> <span class="p">);</span>
<span class="k">constexpr</span> <span class="n">result_type</span> <span class="n">result</span><span class="p">();</span>
<span class="p">};</span></code></pre>
</div>
</div>
<div class="sect5">
<h6 id="ref_xxhash_constructors">Constructors</h6>
<div class="listingblock">
<div class="content">
<pre class="rouge highlight"><code data-lang="c++"><span class="k">constexpr</span> <span class="nf">xxhash_32</span><span class="p">();</span></code></pre>
</div>
</div>
<div class="paragraph">
<p>Default constructor.</p>
</div>
<div class="dlist">
<dl>
<dt class="hdlist1">Effects: </dt>
<dd>
<p>Initializes the internal state of the XXH32 algorithm to its initial values.</p>
</dd>
</dl>
</div>
<div class="listingblock">
<div class="content">
<pre class="rouge highlight"><code data-lang="c++"><span class="k">explicit</span> <span class="k">constexpr</span> <span class="nf">xxhash_32</span><span class="p">(</span> <span class="n">std</span><span class="o">::</span><span class="kt">uint64_t</span> <span class="n">seed</span> <span class="p">);</span></code></pre>
</div>
</div>
<div class="paragraph">
<p>Constructor taking an integer seed value.</p>
</div>
<div class="dlist">
<dl>
<dt class="hdlist1">Effects: </dt>
<dd>
<p>Initializes the internal state of the XXH32 algorithm using the low 32 bits of <code>seed</code> as the seed, then if the high 32 bits of <code>seed</code> aren&#8217;t zero, mixes them into the state.</p>
</dd>
<dt class="hdlist1">Remarks: </dt>
<dd>
<p>By convention, if <code>seed</code> is zero, the effect of this constructor is the same as default construction.</p>
</dd>
</dl>
</div>
<div class="listingblock">
<div class="content">
<pre class="rouge highlight"><code data-lang="c++"><span class="n">xxhash_32</span><span class="p">(</span> <span class="kt">unsigned</span> <span class="kt">char</span> <span class="k">const</span><span class="o">*</span> <span class="n">p</span><span class="p">,</span> <span class="n">std</span><span class="o">::</span><span class="kt">size_t</span> <span class="n">n</span> <span class="p">);</span></code></pre>
</div>
</div>
<div class="paragraph">
<p>Constructor taking a byte sequence seed.</p>
</div>
<div class="dlist">
<dl>
<dt class="hdlist1">Effects: </dt>
<dd>
<p>Initializes the state as if by default construction, then if <code>n</code> is not zero, performs <code>update(p, n); result()</code>.</p>
</dd>
<dt class="hdlist1">Remarks: </dt>
<dd>
<p>By convention, if <code>n</code> is zero, the effect of this constructor is the same as default construction.</p>
</dd>
</dl>
</div>
</div>
<div class="sect5">
<h6 id="ref_xxhash_update">update</h6>
<div class="listingblock">
<div class="content">
<pre class="rouge highlight"><code data-lang="c++"><span class="kt">void</span> <span class="nf">update</span><span class="p">(</span> <span class="kt">void</span> <span class="k">const</span><span class="o">*</span> <span class="n">p</span><span class="p">,</span> <span class="n">std</span><span class="o">::</span><span class="kt">size_t</span> <span class="n">n</span> <span class="p">);</span>
<span class="k">constexpr</span> <span class="kt">void</span> <span class="nf">update</span><span class="p">(</span> <span class="kt">unsigned</span> <span class="kt">char</span> <span class="k">const</span><span class="o">*</span> <span class="n">p</span><span class="p">,</span> <span class="n">std</span><span class="o">::</span><span class="kt">size_t</span> <span class="n">n</span> <span class="p">);</span></code></pre>
</div>
</div>
<div class="dlist">
<dl>
<dt class="hdlist1">Effects: </dt>
<dd>
<p>Updates the internal state of the XXH32 algorithm from the byte sequence <code>[p, p+n)</code>.</p>
</dd>
<dt class="hdlist1">Remarks: </dt>
<dd>
<p>Consecutive calls to <code>update</code> are equivalent to a single call with the concatenated byte sequences of the individual calls.</p>
</dd>
</dl>
</div>
</div>
<div class="sect5">
<h6 id="ref_xxhash_result">result</h6>
<div class="listingblock">
<div class="content">
<pre class="rouge highlight"><code data-lang="c++"><span class="k">constexpr</span> <span class="n">result_type</span> <span class="nf">result</span><span class="p">();</span></code></pre>
</div>
</div>
<div class="dlist">
<dl>
<dt class="hdlist1">Effects: </dt>
<dd>
<p>Obtains a 32 bit hash value from the state as specified by XXH32, then updates the state.</p>
</dd>
<dt class="hdlist1">Returns: </dt>
<dd>
<p>The obtained hash value.</p>
</dd>
<dt class="hdlist1">Remarks: </dt>
<dd>
<p>The state is updated to allow repeated calls to <code>result()</code> to return a pseudorandom sequence of <code>result_type</code> values, effectively extending the output.</p>
</dd>
</dl>
</div>
</div>
</div>
<div class="sect4">
<h5 id="ref_xxhash_xxhash_64">xxhash_64</h5>
<div class="listingblock">
<div class="content">
<pre class="rouge highlight"><code data-lang="c++"><span class="k">class</span> <span class="nc">xxhash_64</span>
<span class="p">{</span>
<span class="nl">public:</span>
<span class="k">using</span> <span class="n">result_type</span> <span class="o">=</span> <span class="n">std</span><span class="o">::</span><span class="kt">uint64_t</span><span class="p">;</span>
<span class="k">constexpr</span> <span class="n">xxhash_64</span><span class="p">();</span>
<span class="k">explicit</span> <span class="k">constexpr</span> <span class="n">xxhash_64</span><span class="p">(</span> <span class="n">std</span><span class="o">::</span><span class="kt">uint64_t</span> <span class="n">seed</span> <span class="p">);</span>
<span class="k">constexpr</span> <span class="n">xxhash_64</span><span class="p">(</span> <span class="kt">unsigned</span> <span class="kt">char</span> <span class="k">const</span><span class="o">*</span> <span class="n">p</span><span class="p">,</span> <span class="n">std</span><span class="o">::</span><span class="kt">size_t</span> <span class="n">n</span> <span class="p">);</span>
<span class="kt">void</span> <span class="n">update</span><span class="p">(</span> <span class="kt">void</span> <span class="k">const</span><span class="o">*</span> <span class="n">p</span><span class="p">,</span> <span class="n">std</span><span class="o">::</span><span class="kt">size_t</span> <span class="n">n</span> <span class="p">);</span>
<span class="k">constexpr</span> <span class="kt">void</span> <span class="n">update</span><span class="p">(</span> <span class="kt">unsigned</span> <span class="kt">char</span> <span class="k">const</span><span class="o">*</span> <span class="n">p</span><span class="p">,</span> <span class="n">std</span><span class="o">::</span><span class="kt">size_t</span> <span class="n">n</span> <span class="p">);</span>
<span class="k">constexpr</span> <span class="n">result_type</span> <span class="n">result</span><span class="p">();</span>
<span class="p">};</span></code></pre>
</div>
</div>
<div class="sect5">
<h6 id="ref_xxhash_constructors_2">Constructors</h6>
<div class="listingblock">
<div class="content">
<pre class="rouge highlight"><code data-lang="c++"><span class="k">constexpr</span> <span class="nf">xxhash_64</span><span class="p">();</span></code></pre>
</div>
</div>
<div class="paragraph">
<p>Default constructor.</p>
</div>
<div class="dlist">
<dl>
<dt class="hdlist1">Effects: </dt>
<dd>
<p>Initializes the internal state of the XXH64 algorithm to its initial values.</p>
</dd>
</dl>
</div>
<div class="listingblock">
<div class="content">
<pre class="rouge highlight"><code data-lang="c++"><span class="k">explicit</span> <span class="k">constexpr</span> <span class="nf">xxhash_64</span><span class="p">(</span> <span class="n">std</span><span class="o">::</span><span class="kt">uint64_t</span> <span class="n">seed</span> <span class="p">);</span></code></pre>
</div>
</div>
<div class="paragraph">
<p>Constructor taking an integer seed value.</p>
</div>
<div class="dlist">
<dl>
<dt class="hdlist1">Effects: </dt>
<dd>
<p>Initializes the internal state of the XXH64 algorithm using <code>seed</code> as the seed.</p>
</dd>
<dt class="hdlist1">Remarks: </dt>
<dd>
<p>By convention, if <code>seed</code> is zero, the effect of this constructor is the same as default construction.</p>
</dd>
</dl>
</div>
<div class="listingblock">
<div class="content">
<pre class="rouge highlight"><code data-lang="c++"><span class="n">xxhash_64</span><span class="p">(</span> <span class="kt">unsigned</span> <span class="kt">char</span> <span class="k">const</span><span class="o">*</span> <span class="n">p</span><span class="p">,</span> <span class="n">std</span><span class="o">::</span><span class="kt">size_t</span> <span class="n">n</span> <span class="p">);</span></code></pre>
</div>
</div>
<div class="paragraph">
<p>Constructor taking a byte sequence seed.</p>
</div>
<div class="dlist">
<dl>
<dt class="hdlist1">Effects: </dt>
<dd>
<p>Initializes the state as if by default construction, then if <code>n</code> is not zero, performs <code>update(p, n); result()</code>.</p>
</dd>
<dt class="hdlist1">Remarks: </dt>
<dd>
<p>By convention, if <code>n</code> is zero, the effect of this constructor is the same as default construction.</p>
</dd>
</dl>
</div>
</div>
<div class="sect5">
<h6 id="ref_xxhash_update_2">update</h6>
<div class="listingblock">
<div class="content">
<pre class="rouge highlight"><code data-lang="c++"><span class="kt">void</span> <span class="nf">update</span><span class="p">(</span> <span class="kt">void</span> <span class="k">const</span><span class="o">*</span> <span class="n">p</span><span class="p">,</span> <span class="n">std</span><span class="o">::</span><span class="kt">size_t</span> <span class="n">n</span> <span class="p">);</span>
<span class="k">constexpr</span> <span class="kt">void</span> <span class="nf">update</span><span class="p">(</span> <span class="kt">unsigned</span> <span class="kt">char</span> <span class="k">const</span><span class="o">*</span> <span class="n">p</span><span class="p">,</span> <span class="n">std</span><span class="o">::</span><span class="kt">size_t</span> <span class="n">n</span> <span class="p">);</span></code></pre>
</div>
</div>
<div class="dlist">
<dl>
<dt class="hdlist1">Effects: </dt>
<dd>
<p>Updates the internal state of the XXH64 algorithm from the byte sequence <code>[p, p+n)</code>.</p>
</dd>
<dt class="hdlist1">Remarks: </dt>
<dd>
<p>Consecutive calls to <code>update</code> are equivalent to a single call with the concatenated byte sequences of the individual calls.</p>
</dd>
</dl>
</div>
</div>
<div class="sect5">
<h6 id="ref_xxhash_result_2">result</h6>
<div class="listingblock">
<div class="content">
<pre class="rouge highlight"><code data-lang="c++"><span class="k">constexpr</span> <span class="n">result_type</span> <span class="nf">result</span><span class="p">();</span></code></pre>
</div>
</div>
<div class="dlist">
<dl>
<dt class="hdlist1">Effects: </dt>
<dd>
<p>Obtains a 64 bit hash value from the state as specified by XXH64, then updates the state.</p>
</dd>
<dt class="hdlist1">Returns: </dt>
<dd>
<p>The obtained hash value.</p>
</dd>
<dt class="hdlist1">Remarks: </dt>
<dd>
<p>The state is updated to allow repeated calls to <code>result()</code> to return a pseudorandom sequence of <code>result_type</code> values, effectively extending the output.</p>
</dd>
</dl>
</div>
</div>
</div>
</div>
<div class="sect3">
<h4 id="ref_siphash">&lt;boost/hash2/siphash.hpp&gt;</h4>
<div class="listingblock">
<div class="content">
<pre class="rouge highlight"><code data-lang="c++"><span class="k">namespace</span> <span class="n">boost</span> <span class="p">{</span>
<span class="k">namespace</span> <span class="n">hash2</span> <span class="p">{</span>
<span class="k">class</span> <span class="nc">siphash_32</span><span class="p">;</span>
<span class="k">class</span> <span class="nc">siphash_64</span><span class="p">;</span>
<span class="p">}</span> <span class="c1">// namespace hash2</span>
<span class="p">}</span> <span class="c1">// namespace boost</span></code></pre>
</div>
</div>
<div class="paragraph">
<p>This header implements the <a href="https://github.com/veorq/SipHash">SipHash and HalfSipHash algorithms</a>.</p>
</div>
<div class="sect4">
<h5 id="ref_siphash_siphash_32">siphash_32</h5>
<div class="listingblock">
<div class="content">
<pre class="rouge highlight"><code data-lang="c++"><span class="k">class</span> <span class="nc">siphash_32</span>
<span class="p">{</span>
<span class="nl">public:</span>
<span class="k">using</span> <span class="n">result_type</span> <span class="o">=</span> <span class="n">std</span><span class="o">::</span><span class="kt">uint32_t</span><span class="p">;</span>
<span class="k">constexpr</span> <span class="n">siphash_32</span><span class="p">();</span>
<span class="k">explicit</span> <span class="k">constexpr</span> <span class="n">siphash_32</span><span class="p">(</span> <span class="n">std</span><span class="o">::</span><span class="kt">uint64_t</span> <span class="n">seed</span> <span class="p">);</span>
<span class="k">constexpr</span> <span class="n">siphash_32</span><span class="p">(</span> <span class="kt">unsigned</span> <span class="kt">char</span> <span class="k">const</span><span class="o">*</span> <span class="n">p</span><span class="p">,</span> <span class="n">std</span><span class="o">::</span><span class="kt">size_t</span> <span class="n">n</span> <span class="p">);</span>
<span class="kt">void</span> <span class="n">update</span><span class="p">(</span> <span class="kt">void</span> <span class="k">const</span><span class="o">*</span> <span class="n">p</span><span class="p">,</span> <span class="n">std</span><span class="o">::</span><span class="kt">size_t</span> <span class="n">n</span> <span class="p">);</span>
<span class="k">constexpr</span> <span class="kt">void</span> <span class="n">update</span><span class="p">(</span> <span class="kt">unsigned</span> <span class="kt">char</span> <span class="k">const</span><span class="o">*</span> <span class="n">p</span><span class="p">,</span> <span class="n">std</span><span class="o">::</span><span class="kt">size_t</span> <span class="n">n</span> <span class="p">);</span>
<span class="k">constexpr</span> <span class="n">result_type</span> <span class="n">result</span><span class="p">();</span>
<span class="p">};</span></code></pre>
</div>
</div>
<div class="sect5">
<h6 id="ref_siphash_constructors">Constructors</h6>
<div class="listingblock">
<div class="content">
<pre class="rouge highlight"><code data-lang="c++"><span class="k">constexpr</span> <span class="nf">siphash_32</span><span class="p">();</span></code></pre>
</div>
</div>
<div class="paragraph">
<p>Default constructor.</p>
</div>
<div class="dlist">
<dl>
<dt class="hdlist1">Effects: </dt>
<dd>
<p>Initializes the internal state of the HalfSipHash algorithm as if using a sequence of 8 zero bytes as the key.</p>
</dd>
</dl>
</div>
<div class="listingblock">
<div class="content">
<pre class="rouge highlight"><code data-lang="c++"><span class="k">explicit</span> <span class="k">constexpr</span> <span class="nf">siphash_32</span><span class="p">(</span> <span class="n">std</span><span class="o">::</span><span class="kt">uint64_t</span> <span class="n">seed</span> <span class="p">);</span></code></pre>
</div>
</div>
<div class="paragraph">
<p>Constructor taking an integer seed value.</p>
</div>
<div class="dlist">
<dl>
<dt class="hdlist1">Effects: </dt>
<dd>
<p>Initializes the internal state of the HalfSipHash algorithm using <code>seed</code> as the key, as if it were a sequence of its 8 constituent bytes, in little-endian order.</p>
</dd>
<dt class="hdlist1">Remarks: </dt>
<dd>
<p>By convention, if <code>seed</code> is zero, the effect of this constructor is the same as default construction.</p>
</dd>
</dl>
</div>
<div class="listingblock">
<div class="content">
<pre class="rouge highlight"><code data-lang="c++"><span class="n">siphash_32</span><span class="p">(</span> <span class="kt">unsigned</span> <span class="kt">char</span> <span class="k">const</span><span class="o">*</span> <span class="n">p</span><span class="p">,</span> <span class="n">std</span><span class="o">::</span><span class="kt">size_t</span> <span class="n">n</span> <span class="p">);</span></code></pre>
</div>
</div>
<div class="paragraph">
<p>Constructor taking a byte sequence seed.</p>
</div>
<div class="dlist">
<dl>
<dt class="hdlist1">Effects: </dt>
<dd>
<p>If <code>n</code> is 8, initializes the state as specified by the algorithm; otherwise, initializes the state as if by default construction, then if <code>n</code> is not zero, performs <code>update(p, n); result()</code>.</p>
</dd>
<dt class="hdlist1">Remarks: </dt>
<dd>
<p>By convention, if <code>n</code> is zero, the effect of this constructor is the same as default construction.</p>
</dd>
</dl>
</div>
</div>
<div class="sect5">
<h6 id="ref_siphash_update">update</h6>
<div class="listingblock">
<div class="content">
<pre class="rouge highlight"><code data-lang="c++"><span class="kt">void</span> <span class="nf">update</span><span class="p">(</span> <span class="kt">void</span> <span class="k">const</span><span class="o">*</span> <span class="n">p</span><span class="p">,</span> <span class="n">std</span><span class="o">::</span><span class="kt">size_t</span> <span class="n">n</span> <span class="p">);</span>
<span class="k">constexpr</span> <span class="kt">void</span> <span class="nf">update</span><span class="p">(</span> <span class="kt">unsigned</span> <span class="kt">char</span> <span class="k">const</span><span class="o">*</span> <span class="n">p</span><span class="p">,</span> <span class="n">std</span><span class="o">::</span><span class="kt">size_t</span> <span class="n">n</span> <span class="p">);</span></code></pre>
</div>
</div>
<div class="dlist">
<dl>
<dt class="hdlist1">Effects: </dt>
<dd>
<p>Updates the internal state of the HalfSipHash algorithm from the byte sequence <code>[p, p+n)</code>.</p>
</dd>
<dt class="hdlist1">Remarks: </dt>
<dd>
<p>Consecutive calls to <code>update</code> are equivalent to a single call with the concatenated byte sequences of the individual calls.</p>
</dd>
</dl>
</div>
</div>
<div class="sect5">
<h6 id="ref_siphash_result">result</h6>
<div class="listingblock">
<div class="content">
<pre class="rouge highlight"><code data-lang="c++"><span class="k">constexpr</span> <span class="n">result_type</span> <span class="nf">result</span><span class="p">();</span></code></pre>
</div>
</div>
<div class="dlist">
<dl>
<dt class="hdlist1">Effects: </dt>
<dd>
<p>Obtains a 32 bit hash value from the state as specified by HalfSipHash.</p>
</dd>
<dt class="hdlist1">Returns: </dt>
<dd>
<p>The obtained hash value.</p>
</dd>
<dt class="hdlist1">Remarks: </dt>
<dd>
<p>The state is updated, which allows repeated calls to <code>result()</code> to return a pseudorandom sequence of <code>result_type</code> values, effectively extending the output.</p>
</dd>
</dl>
</div>
</div>
</div>
<div class="sect4">
<h5 id="ref_siphash_siphash_64">siphash_64</h5>
<div class="listingblock">
<div class="content">
<pre class="rouge highlight"><code data-lang="c++"><span class="k">class</span> <span class="nc">siphash_64</span>
<span class="p">{</span>
<span class="nl">public:</span>
<span class="k">using</span> <span class="n">result_type</span> <span class="o">=</span> <span class="n">std</span><span class="o">::</span><span class="kt">uint64_t</span><span class="p">;</span>
<span class="k">constexpr</span> <span class="n">siphash_64</span><span class="p">();</span>
<span class="k">explicit</span> <span class="k">constexpr</span> <span class="n">siphash_64</span><span class="p">(</span> <span class="n">std</span><span class="o">::</span><span class="kt">uint64_t</span> <span class="n">seed</span> <span class="p">);</span>
<span class="k">constexpr</span> <span class="n">siphash_64</span><span class="p">(</span> <span class="kt">unsigned</span> <span class="kt">char</span> <span class="k">const</span><span class="o">*</span> <span class="n">p</span><span class="p">,</span> <span class="n">std</span><span class="o">::</span><span class="kt">size_t</span> <span class="n">n</span> <span class="p">);</span>
<span class="kt">void</span> <span class="n">update</span><span class="p">(</span> <span class="kt">void</span> <span class="k">const</span><span class="o">*</span> <span class="n">p</span><span class="p">,</span> <span class="n">std</span><span class="o">::</span><span class="kt">size_t</span> <span class="n">n</span> <span class="p">);</span>
<span class="k">constexpr</span> <span class="kt">void</span> <span class="n">update</span><span class="p">(</span> <span class="kt">unsigned</span> <span class="kt">char</span> <span class="k">const</span><span class="o">*</span> <span class="n">p</span><span class="p">,</span> <span class="n">std</span><span class="o">::</span><span class="kt">size_t</span> <span class="n">n</span> <span class="p">);</span>
<span class="k">constexpr</span> <span class="n">result_type</span> <span class="n">result</span><span class="p">();</span>
<span class="p">};</span></code></pre>
</div>
</div>
<div class="sect5">
<h6 id="ref_siphash_constructors_2">Constructors</h6>
<div class="listingblock">
<div class="content">
<pre class="rouge highlight"><code data-lang="c++"><span class="k">constexpr</span> <span class="nf">siphash_64</span><span class="p">();</span></code></pre>
</div>
</div>
<div class="paragraph">
<p>Default constructor.</p>
</div>
<div class="dlist">
<dl>
<dt class="hdlist1">Effects: </dt>
<dd>
<p>Initializes the internal state of the SipHash algorithm as if using a sequence of 16 zero bytes as the key.</p>
</dd>
</dl>
</div>
<div class="listingblock">
<div class="content">
<pre class="rouge highlight"><code data-lang="c++"><span class="k">explicit</span> <span class="k">constexpr</span> <span class="nf">siphash_64</span><span class="p">(</span> <span class="n">std</span><span class="o">::</span><span class="kt">uint64_t</span> <span class="n">seed</span> <span class="p">);</span></code></pre>
</div>
</div>
<div class="paragraph">
<p>Constructor taking an integer seed value.</p>
</div>
<div class="dlist">
<dl>
<dt class="hdlist1">Effects: </dt>
<dd>
<p>Initializes the internal state of the SipHash algorithm using <code>seed</code> as the key, as if it were a sequence of its 8 constituent bytes, in little-endian order, followed by 8 zero bytes.</p>
</dd>
<dt class="hdlist1">Remarks: </dt>
<dd>
<p>By convention, if <code>seed</code> is zero, the effect of this constructor is the same as default construction.</p>
</dd>
</dl>
</div>
<div class="listingblock">
<div class="content">
<pre class="rouge highlight"><code data-lang="c++"><span class="n">siphash_64</span><span class="p">(</span> <span class="kt">unsigned</span> <span class="kt">char</span> <span class="k">const</span><span class="o">*</span> <span class="n">p</span><span class="p">,</span> <span class="n">std</span><span class="o">::</span><span class="kt">size_t</span> <span class="n">n</span> <span class="p">);</span></code></pre>
</div>
</div>
<div class="paragraph">
<p>Constructor taking a byte sequence seed.</p>
</div>
<div class="dlist">
<dl>
<dt class="hdlist1">Effects: </dt>
<dd>
<p>If <code>n</code> is 16, initializes the state as specified by the algorithm; otherwise, initializes the state as if by default construction, then if <code>n</code> is not zero, performs <code>update(p, n); result()</code>.</p>
</dd>
<dt class="hdlist1">Remarks: </dt>
<dd>
<p>By convention, if <code>n</code> is zero, the effect of this constructor is the same as default construction.</p>
</dd>
</dl>
</div>
</div>
<div class="sect5">
<h6 id="ref_siphash_update_2">update</h6>
<div class="listingblock">
<div class="content">
<pre class="rouge highlight"><code data-lang="c++"><span class="kt">void</span> <span class="nf">update</span><span class="p">(</span> <span class="kt">void</span> <span class="k">const</span><span class="o">*</span> <span class="n">p</span><span class="p">,</span> <span class="n">std</span><span class="o">::</span><span class="kt">size_t</span> <span class="n">n</span> <span class="p">);</span>
<span class="k">constexpr</span> <span class="kt">void</span> <span class="nf">update</span><span class="p">(</span> <span class="kt">unsigned</span> <span class="kt">char</span> <span class="k">const</span><span class="o">*</span> <span class="n">p</span><span class="p">,</span> <span class="n">std</span><span class="o">::</span><span class="kt">size_t</span> <span class="n">n</span> <span class="p">);</span></code></pre>
</div>
</div>
<div class="dlist">
<dl>
<dt class="hdlist1">Effects: </dt>
<dd>
<p>Updates the internal state of the SipHash algorithm from the byte sequence <code>[p, p+n)</code>.</p>
</dd>
<dt class="hdlist1">Remarks: </dt>
<dd>
<p>Consecutive calls to <code>update</code> are equivalent to a single call with the concatenated byte sequences of the individual calls.</p>
</dd>
</dl>
</div>
</div>
<div class="sect5">
<h6 id="ref_siphash_result_2">result</h6>
<div class="listingblock">
<div class="content">
<pre class="rouge highlight"><code data-lang="c++"><span class="k">constexpr</span> <span class="n">result_type</span> <span class="nf">result</span><span class="p">();</span></code></pre>
</div>
</div>
<div class="dlist">
<dl>
<dt class="hdlist1">Effects: </dt>
<dd>
<p>Obtains a 64 bit hash value from the state as specified by SipHash, then updates the state.</p>
</dd>
<dt class="hdlist1">Returns: </dt>
<dd>
<p>The obtained hash value.</p>
</dd>
<dt class="hdlist1">Remarks: </dt>
<dd>
<p>The state is updated, which allows repeated calls to <code>result()</code> to return a pseudorandom sequence of <code>result_type</code> values, effectively extending the output.</p>
</dd>
</dl>
</div>
</div>
</div>
</div>
<div class="sect3">
<h4 id="ref_hmac">&lt;boost/hash2/hmac.hpp&gt;</h4>
<div class="listingblock">
<div class="content">
<pre class="rouge highlight"><code data-lang="c++"><span class="k">namespace</span> <span class="n">boost</span> <span class="p">{</span>
<span class="k">namespace</span> <span class="n">hash2</span> <span class="p">{</span>
<span class="k">template</span><span class="o">&lt;</span><span class="k">class</span> <span class="nc">H</span><span class="p">&gt;</span> <span class="k">class</span> <span class="nc">hmac</span><span class="p">;</span>
<span class="p">}</span> <span class="c1">// namespace hash2</span>
<span class="p">}</span> <span class="c1">// namespace boost</span></code></pre>
</div>
</div>
<div class="paragraph">
<p>This header implements the <a href="https://tools.ietf.org/html/rfc2104">HMAC algorithm</a>.</p>
</div>
<div class="sect4">
<h5 id="ref_hmac_hmac">hmac</h5>
<div class="listingblock">
<div class="content">
<pre class="rouge highlight"><code data-lang="c++"><span class="k">template</span><span class="o">&lt;</span><span class="k">class</span> <span class="nc">H</span><span class="p">&gt;</span> <span class="k">class</span> <span class="nc">hmac</span>
<span class="p">{</span>
<span class="nl">public:</span>
<span class="k">using</span> <span class="n">result_type</span> <span class="o">=</span> <span class="k">typename</span> <span class="n">H</span><span class="o">::</span><span class="n">result_type</span><span class="p">;</span>
<span class="k">static</span> <span class="k">constexpr</span> <span class="kt">int</span> <span class="n">block_size</span> <span class="o">=</span> <span class="n">H</span><span class="o">::</span><span class="n">block_size</span><span class="p">;</span>
<span class="k">constexpr</span> <span class="n">hmac</span><span class="p">();</span>
<span class="k">explicit</span> <span class="k">constexpr</span> <span class="n">hmac</span><span class="p">(</span> <span class="n">std</span><span class="o">::</span><span class="kt">uint64_t</span> <span class="n">seed</span> <span class="p">);</span>
<span class="k">constexpr</span> <span class="n">hmac</span><span class="p">(</span> <span class="kt">unsigned</span> <span class="kt">char</span> <span class="k">const</span><span class="o">*</span> <span class="n">p</span><span class="p">,</span> <span class="n">std</span><span class="o">::</span><span class="kt">size_t</span> <span class="n">n</span> <span class="p">);</span>
<span class="kt">void</span> <span class="n">update</span><span class="p">(</span> <span class="kt">void</span> <span class="k">const</span><span class="o">*</span> <span class="n">p</span><span class="p">,</span> <span class="n">std</span><span class="o">::</span><span class="kt">size_t</span> <span class="n">n</span> <span class="p">);</span>
<span class="k">constexpr</span> <span class="kt">void</span> <span class="n">update</span><span class="p">(</span> <span class="kt">unsigned</span> <span class="kt">char</span> <span class="k">const</span><span class="o">*</span> <span class="n">p</span><span class="p">,</span> <span class="n">std</span><span class="o">::</span><span class="kt">size_t</span> <span class="n">n</span> <span class="p">);</span>
<span class="k">constexpr</span> <span class="n">result_type</span> <span class="n">result</span><span class="p">();</span>
<span class="p">};</span></code></pre>
</div>
</div>
<div class="paragraph">
<p>The class template <code>hmac</code> takes as a parameter a cryptographic <em>hash algorithm</em> <code>H</code>
and implements the corresponding <em>hash-based message authentication code</em> (HMAC) algorithm.</p>
</div>
<div class="paragraph">
<p>For example, HMAC-SHA2-256 is implemented by <code>hmac&lt;sha2_256&gt;</code>.</p>
</div>
<div class="sect5">
<h6 id="ref_hmac_constructors">Constructors</h6>
<div class="listingblock">
<div class="content">
<pre class="rouge highlight"><code data-lang="c++"><span class="k">constexpr</span> <span class="nf">hmac</span><span class="p">();</span></code></pre>
</div>
</div>
<div class="paragraph">
<p>Default constructor.</p>
</div>
<div class="dlist">
<dl>
<dt class="hdlist1">Effects: </dt>
<dd>
<p>Initializes the internal state using an empty byte sequence as the secret key.</p>
</dd>
</dl>
</div>
<div class="listingblock">
<div class="content">
<pre class="rouge highlight"><code data-lang="c++"><span class="k">explicit</span> <span class="k">constexpr</span> <span class="nf">hmac</span><span class="p">(</span> <span class="n">std</span><span class="o">::</span><span class="kt">uint64_t</span> <span class="n">seed</span> <span class="p">);</span></code></pre>
</div>
</div>
<div class="paragraph">
<p>Constructor taking an integer seed value.</p>
</div>
<div class="dlist">
<dl>
<dt class="hdlist1">Effects: </dt>
<dd>
<p>If <code>seed</code> is zero, initializes the state as if by default construction, otherwise, initializes it using the 8 bytes of the little-endian representation of <code>seed</code> as the secret key.</p>
</dd>
<dt class="hdlist1">Remarks: </dt>
<dd>
<p>By convention, if <code>seed</code> is zero, the effect of this constructor is the same as default construction.</p>
</dd>
</dl>
</div>
<div class="listingblock">
<div class="content">
<pre class="rouge highlight"><code data-lang="c++"><span class="n">hmac</span><span class="p">(</span> <span class="kt">unsigned</span> <span class="kt">char</span> <span class="k">const</span><span class="o">*</span> <span class="n">p</span><span class="p">,</span> <span class="n">std</span><span class="o">::</span><span class="kt">size_t</span> <span class="n">n</span> <span class="p">);</span></code></pre>
</div>
</div>
<div class="paragraph">
<p>Constructor taking a byte sequence seed.</p>
</div>
<div class="dlist">
<dl>
<dt class="hdlist1">Effects: </dt>
<dd>
<p>Initializes the state as specified by the HMAC algorithm using <code>[p, p+n)</code> as the secret key.</p>
</dd>
<dt class="hdlist1">Remarks: </dt>
<dd>
<p>By convention, if <code>n</code> is zero, the effect of this constructor is the same as default construction.</p>
</dd>
</dl>
</div>
</div>
<div class="sect5">
<h6 id="ref_hmac_update">update</h6>
<div class="listingblock">
<div class="content">
<pre class="rouge highlight"><code data-lang="c++"><span class="kt">void</span> <span class="nf">update</span><span class="p">(</span> <span class="kt">void</span> <span class="k">const</span><span class="o">*</span> <span class="n">p</span><span class="p">,</span> <span class="n">std</span><span class="o">::</span><span class="kt">size_t</span> <span class="n">n</span> <span class="p">);</span>
<span class="k">constexpr</span> <span class="kt">void</span> <span class="nf">update</span><span class="p">(</span> <span class="kt">unsigned</span> <span class="kt">char</span> <span class="k">const</span><span class="o">*</span> <span class="n">p</span><span class="p">,</span> <span class="n">std</span><span class="o">::</span><span class="kt">size_t</span> <span class="n">n</span> <span class="p">);</span></code></pre>
</div>
</div>
<div class="dlist">
<dl>
<dt class="hdlist1">Effects: </dt>
<dd>
<p>Updates the internal state of the HMAC algorithm from the byte sequence <code>[p, p+n)</code>.</p>
</dd>
<dt class="hdlist1">Remarks: </dt>
<dd>
<p>Consecutive calls to <code>update</code> are equivalent to a single call with the concatenated byte sequences of the individual calls.</p>
</dd>
</dl>
</div>
</div>
<div class="sect5">
<h6 id="ref_hmac_result">result</h6>
<div class="listingblock">
<div class="content">
<pre class="rouge highlight"><code data-lang="c++"><span class="k">constexpr</span> <span class="n">result_type</span> <span class="nf">result</span><span class="p">();</span></code></pre>
</div>
</div>
<div class="dlist">
<dl>
<dt class="hdlist1">Effects: </dt>
<dd>
<p>Pads the accumulated message and finalizes the HMAC digest.</p>
</dd>
<dt class="hdlist1">Returns: </dt>
<dd>
<p>The HMAC digest of the message formed from the byte sequences of the preceding calls to <code>update</code>.</p>
</dd>
<dt class="hdlist1">Remarks: </dt>
<dd>
<p>Repeated calls to <code>result()</code> return a pseudorandom sequence of <code>result_type</code> values, effectively extending the output.</p>
</dd>
</dl>
</div>
</div>
</div>
</div>
<div class="sect3">
<h4 id="ref_md5">&lt;boost/hash2/md5.hpp&gt;</h4>
<div class="listingblock">
<div class="content">
<pre class="rouge highlight"><code data-lang="c++"><span class="cp">#include</span> <span class="cpf">&lt;boost/hash2/hmac.hpp&gt;</span><span class="cp">
#include</span> <span class="cpf">&lt;boost/hash2/digest.hpp&gt;</span><span class="cp">
</span>
<span class="k">namespace</span> <span class="n">boost</span> <span class="p">{</span>
<span class="k">namespace</span> <span class="n">hash2</span> <span class="p">{</span>
<span class="k">class</span> <span class="nc">md5_128</span><span class="p">;</span>
<span class="k">using</span> <span class="n">hmac_md5_128</span> <span class="o">=</span> <span class="n">hmac</span><span class="o">&lt;</span><span class="n">md5_128</span><span class="o">&gt;</span><span class="p">;</span>
<span class="p">}</span> <span class="c1">// namespace hash2</span>
<span class="p">}</span> <span class="c1">// namespace boost</span></code></pre>
</div>
</div>
<div class="paragraph">
<p>This header implements the <a href="https://tools.ietf.org/html/rfc1321">MD5 algorithm</a>.</p>
</div>
<div class="sect4">
<h5 id="ref_md5_md5_128">md5_128</h5>
<div class="listingblock">
<div class="content">
<pre class="rouge highlight"><code data-lang="c++"><span class="k">class</span> <span class="nc">md5_128</span>
<span class="p">{</span>
<span class="nl">public:</span>
<span class="k">using</span> <span class="n">result_type</span> <span class="o">=</span> <span class="n">digest</span><span class="o">&lt;</span><span class="mi">16</span><span class="o">&gt;</span><span class="p">;</span>
<span class="k">static</span> <span class="k">constexpr</span> <span class="kt">int</span> <span class="n">block_size</span> <span class="o">=</span> <span class="mi">64</span><span class="p">;</span>
<span class="k">constexpr</span> <span class="n">md5_128</span><span class="p">();</span>
<span class="k">explicit</span> <span class="k">constexpr</span> <span class="n">md5_128</span><span class="p">(</span> <span class="n">std</span><span class="o">::</span><span class="kt">uint64_t</span> <span class="n">seed</span> <span class="p">);</span>
<span class="k">constexpr</span> <span class="n">md5_128</span><span class="p">(</span> <span class="kt">unsigned</span> <span class="kt">char</span> <span class="k">const</span><span class="o">*</span> <span class="n">p</span><span class="p">,</span> <span class="n">std</span><span class="o">::</span><span class="kt">size_t</span> <span class="n">n</span> <span class="p">);</span>
<span class="kt">void</span> <span class="n">update</span><span class="p">(</span> <span class="kt">void</span> <span class="k">const</span><span class="o">*</span> <span class="n">p</span><span class="p">,</span> <span class="n">std</span><span class="o">::</span><span class="kt">size_t</span> <span class="n">n</span> <span class="p">);</span>
<span class="k">constexpr</span> <span class="kt">void</span> <span class="n">update</span><span class="p">(</span> <span class="kt">unsigned</span> <span class="kt">char</span> <span class="k">const</span><span class="o">*</span> <span class="n">p</span><span class="p">,</span> <span class="n">std</span><span class="o">::</span><span class="kt">size_t</span> <span class="n">n</span> <span class="p">);</span>
<span class="k">constexpr</span> <span class="n">result_type</span> <span class="n">result</span><span class="p">();</span>
<span class="p">};</span></code></pre>
</div>
</div>
<div class="sect5">
<h6 id="ref_md5_constructors">Constructors</h6>
<div class="listingblock">
<div class="content">
<pre class="rouge highlight"><code data-lang="c++"><span class="k">constexpr</span> <span class="nf">md5_128</span><span class="p">();</span></code></pre>
</div>
</div>
<div class="paragraph">
<p>Default constructor.</p>
</div>
<div class="dlist">
<dl>
<dt class="hdlist1">Effects: </dt>
<dd>
<p>Initializes the internal state of the MD5 algorithm to its initial values.</p>
</dd>
</dl>
</div>
<div class="listingblock">
<div class="content">
<pre class="rouge highlight"><code data-lang="c++"><span class="k">explicit</span> <span class="k">constexpr</span> <span class="nf">md5_128</span><span class="p">(</span> <span class="n">std</span><span class="o">::</span><span class="kt">uint64_t</span> <span class="n">seed</span> <span class="p">);</span></code></pre>
</div>
</div>
<div class="paragraph">
<p>Constructor taking an integer seed value.</p>
</div>
<div class="dlist">
<dl>
<dt class="hdlist1">Effects: </dt>
<dd>
<p>Initializes the state as if by default construction, then if <code>seed</code> is not zero, performs <code>update(p, 8); result();</code> where <code>p</code> points to a little-endian representation of the value of <code>seed</code>.</p>
</dd>
<dt class="hdlist1">Remarks: </dt>
<dd>
<p>By convention, if <code>seed</code> is zero, the effect of this constructor is the same as default construction.</p>
</dd>
</dl>
</div>
<div class="listingblock">
<div class="content">
<pre class="rouge highlight"><code data-lang="c++"><span class="n">md5_128</span><span class="p">(</span> <span class="kt">unsigned</span> <span class="kt">char</span> <span class="k">const</span><span class="o">*</span> <span class="n">p</span><span class="p">,</span> <span class="n">std</span><span class="o">::</span><span class="kt">size_t</span> <span class="n">n</span> <span class="p">);</span></code></pre>
</div>
</div>
<div class="paragraph">
<p>Constructor taking a byte sequence seed.</p>
</div>
<div class="dlist">
<dl>
<dt class="hdlist1">Effects: </dt>
<dd>
<p>Initializes the state as if by default construction, then if <code>n</code> is not zero, performs <code>update(p, n); result()</code>.</p>
</dd>
<dt class="hdlist1">Remarks: </dt>
<dd>
<p>By convention, if <code>n</code> is zero, the effect of this constructor is the same as default construction.</p>
</dd>
</dl>
</div>
</div>
<div class="sect5">
<h6 id="ref_md5_update">update</h6>
<div class="listingblock">
<div class="content">
<pre class="rouge highlight"><code data-lang="c++"><span class="kt">void</span> <span class="nf">update</span><span class="p">(</span> <span class="kt">void</span> <span class="k">const</span><span class="o">*</span> <span class="n">p</span><span class="p">,</span> <span class="n">std</span><span class="o">::</span><span class="kt">size_t</span> <span class="n">n</span> <span class="p">);</span>
<span class="k">constexpr</span> <span class="kt">void</span> <span class="nf">update</span><span class="p">(</span> <span class="kt">unsigned</span> <span class="kt">char</span> <span class="k">const</span><span class="o">*</span> <span class="n">p</span><span class="p">,</span> <span class="n">std</span><span class="o">::</span><span class="kt">size_t</span> <span class="n">n</span> <span class="p">);</span></code></pre>
</div>
</div>
<div class="dlist">
<dl>
<dt class="hdlist1">Effects: </dt>
<dd>
<p>Updates the internal state of the MD5 algorithm from the byte sequence <code>[p, p+n)</code>.</p>
</dd>
<dt class="hdlist1">Remarks: </dt>
<dd>
<p>Consecutive calls to <code>update</code> are equivalent to a single call with the concatenated byte sequences of the individual calls.</p>
</dd>
</dl>
</div>
</div>
<div class="sect5">
<h6 id="ref_md5_result">result</h6>
<div class="listingblock">
<div class="content">
<pre class="rouge highlight"><code data-lang="c++"><span class="k">constexpr</span> <span class="n">result_type</span> <span class="nf">result</span><span class="p">();</span></code></pre>
</div>
</div>
<div class="dlist">
<dl>
<dt class="hdlist1">Effects: </dt>
<dd>
<p>Pads the accumulated message and finalizes the MD5 digest.</p>
</dd>
<dt class="hdlist1">Returns: </dt>
<dd>
<p>The MD5 digest of the message formed from the byte sequences of the preceding calls to <code>update</code>.</p>
</dd>
<dt class="hdlist1">Remarks: </dt>
<dd>
<p>Repeated calls to <code>result()</code> return a pseudorandom sequence of <code>result_type</code> values, effectively extending the output.</p>
</dd>
</dl>
</div>
</div>
</div>
</div>
<div class="sect3">
<h4 id="ref_sha1">&lt;boost/hash2/sha1.hpp&gt;</h4>
<div class="listingblock">
<div class="content">
<pre class="rouge highlight"><code data-lang="c++"><span class="cp">#include</span> <span class="cpf">&lt;boost/hash2/hmac.hpp&gt;</span><span class="cp">
#include</span> <span class="cpf">&lt;boost/hash2/digest.hpp&gt;</span><span class="cp">
</span>
<span class="k">namespace</span> <span class="n">boost</span> <span class="p">{</span>
<span class="k">namespace</span> <span class="n">hash2</span> <span class="p">{</span>
<span class="k">class</span> <span class="nc">sha1_160</span><span class="p">;</span>
<span class="k">using</span> <span class="n">hmac_sha1_160</span> <span class="o">=</span> <span class="n">hmac</span><span class="o">&lt;</span><span class="n">sha1_160</span><span class="o">&gt;</span><span class="p">;</span>
<span class="p">}</span> <span class="c1">// namespace hash2</span>
<span class="p">}</span> <span class="c1">// namespace boost</span></code></pre>
</div>
</div>
<div class="paragraph">
<p>This header implements the <a href="https://tools.ietf.org/html/rfc3174">SHA-1 algorithm</a>.</p>
</div>
<div class="sect4">
<h5 id="ref_sha1_sha1_160">sha1_160</h5>
<div class="listingblock">
<div class="content">
<pre class="rouge highlight"><code data-lang="c++"><span class="k">class</span> <span class="nc">sha1_160</span>
<span class="p">{</span>
<span class="nl">public:</span>
<span class="k">using</span> <span class="n">result_type</span> <span class="o">=</span> <span class="n">digest</span><span class="o">&lt;</span><span class="mi">20</span><span class="o">&gt;</span><span class="p">;</span>
<span class="k">static</span> <span class="k">constexpr</span> <span class="kt">int</span> <span class="n">block_size</span> <span class="o">=</span> <span class="mi">64</span><span class="p">;</span>
<span class="k">constexpr</span> <span class="n">sha1_160</span><span class="p">();</span>
<span class="k">explicit</span> <span class="k">constexpr</span> <span class="n">sha1_160</span><span class="p">(</span> <span class="n">std</span><span class="o">::</span><span class="kt">uint64_t</span> <span class="n">seed</span> <span class="p">);</span>
<span class="k">constexpr</span> <span class="n">sha1_160</span><span class="p">(</span> <span class="kt">unsigned</span> <span class="kt">char</span> <span class="k">const</span><span class="o">*</span> <span class="n">p</span><span class="p">,</span> <span class="n">std</span><span class="o">::</span><span class="kt">size_t</span> <span class="n">n</span> <span class="p">);</span>
<span class="kt">void</span> <span class="n">update</span><span class="p">(</span> <span class="kt">void</span> <span class="k">const</span><span class="o">*</span> <span class="n">p</span><span class="p">,</span> <span class="n">std</span><span class="o">::</span><span class="kt">size_t</span> <span class="n">n</span> <span class="p">);</span>
<span class="k">constexpr</span> <span class="kt">void</span> <span class="n">update</span><span class="p">(</span> <span class="kt">unsigned</span> <span class="kt">char</span> <span class="k">const</span><span class="o">*</span> <span class="n">p</span><span class="p">,</span> <span class="n">std</span><span class="o">::</span><span class="kt">size_t</span> <span class="n">n</span> <span class="p">);</span>
<span class="k">constexpr</span> <span class="n">result_type</span> <span class="n">result</span><span class="p">();</span>
<span class="p">};</span></code></pre>
</div>
</div>
<div class="sect5">
<h6 id="ref_sha1_constructors">Constructors</h6>
<div class="listingblock">
<div class="content">
<pre class="rouge highlight"><code data-lang="c++"><span class="k">constexpr</span> <span class="nf">sha1_160</span><span class="p">();</span></code></pre>
</div>
</div>
<div class="paragraph">
<p>Default constructor.</p>
</div>
<div class="dlist">
<dl>
<dt class="hdlist1">Effects: </dt>
<dd>
<p>Initializes the internal state of the SHA-1 algorithm to its initial values.</p>
</dd>
</dl>
</div>
<div class="listingblock">
<div class="content">
<pre class="rouge highlight"><code data-lang="c++"><span class="k">explicit</span> <span class="k">constexpr</span> <span class="nf">sha1_160</span><span class="p">(</span> <span class="n">std</span><span class="o">::</span><span class="kt">uint64_t</span> <span class="n">seed</span> <span class="p">);</span></code></pre>
</div>
</div>
<div class="paragraph">
<p>Constructor taking an integer seed value.</p>
</div>
<div class="dlist">
<dl>
<dt class="hdlist1">Effects: </dt>
<dd>
<p>Initializes the state as if by default construction, then if <code>seed</code> is not zero, performs <code>update(p, 8); result();</code> where <code>p</code> points to a little-endian representation of the value of <code>seed</code>.</p>
</dd>
<dt class="hdlist1">Remarks: </dt>
<dd>
<p>By convention, if <code>seed</code> is zero, the effect of this constructor is the same as default construction.</p>
</dd>
</dl>
</div>
<div class="listingblock">
<div class="content">
<pre class="rouge highlight"><code data-lang="c++"><span class="k">constexpr</span> <span class="nf">sha1_160</span><span class="p">(</span> <span class="kt">unsigned</span> <span class="kt">char</span> <span class="k">const</span><span class="o">*</span> <span class="n">p</span><span class="p">,</span> <span class="n">std</span><span class="o">::</span><span class="kt">size_t</span> <span class="n">n</span> <span class="p">);</span></code></pre>
</div>
</div>
<div class="paragraph">
<p>Constructor taking a byte sequence seed.</p>
</div>
<div class="dlist">
<dl>
<dt class="hdlist1">Effects: </dt>
<dd>
<p>Initializes the state as if by default construction, then if <code>n</code> is not zero, performs <code>update(p, n); result()</code>.</p>
</dd>
<dt class="hdlist1">Remarks: </dt>
<dd>
<p>By convention, if <code>n</code> is zero, the effect of this constructor is the same as default construction.</p>
</dd>
</dl>
</div>
</div>
<div class="sect5">
<h6 id="ref_sha1_update">update</h6>
<div class="listingblock">
<div class="content">
<pre class="rouge highlight"><code data-lang="c++"><span class="kt">void</span> <span class="nf">update</span><span class="p">(</span> <span class="kt">void</span> <span class="k">const</span><span class="o">*</span> <span class="n">p</span><span class="p">,</span> <span class="n">std</span><span class="o">::</span><span class="kt">size_t</span> <span class="n">n</span> <span class="p">);</span>
<span class="k">constexpr</span> <span class="kt">void</span> <span class="nf">update</span><span class="p">(</span> <span class="kt">unsigned</span> <span class="kt">char</span> <span class="k">const</span><span class="o">*</span> <span class="n">p</span><span class="p">,</span> <span class="n">std</span><span class="o">::</span><span class="kt">size_t</span> <span class="n">n</span> <span class="p">);</span></code></pre>
</div>
</div>
<div class="dlist">
<dl>
<dt class="hdlist1">Effects: </dt>
<dd>
<p>Updates the internal state of the SHA-1 algorithm from the byte sequence <code>[p, p+n)</code>.</p>
</dd>
<dt class="hdlist1">Remarks: </dt>
<dd>
<p>Consecutive calls to <code>update</code> are equivalent to a single call with the concatenated byte sequences of the individual calls.</p>
</dd>
</dl>
</div>
</div>
<div class="sect5">
<h6 id="ref_sha1_result">result</h6>
<div class="listingblock">
<div class="content">
<pre class="rouge highlight"><code data-lang="c++"><span class="k">constexpr</span> <span class="n">result_type</span> <span class="nf">result</span><span class="p">();</span></code></pre>
</div>
</div>
<div class="dlist">
<dl>
<dt class="hdlist1">Effects: </dt>
<dd>
<p>Pads the accumulated message and finalizes the SHA-1 digest.</p>
</dd>
<dt class="hdlist1">Returns: </dt>
<dd>
<p>The SHA-1 digest of the message formed from the byte sequences of the preceding calls to <code>update</code>.</p>
</dd>
<dt class="hdlist1">Remarks: </dt>
<dd>
<p>Repeated calls to <code>result()</code> return a pseudorandom sequence of <code>result_type</code> values, effectively extending the output.</p>
</dd>
</dl>
</div>
</div>
</div>
</div>
<div class="sect3">
<h4 id="ref_sha2">&lt;boost/hash2/sha2.hpp&gt;</h4>
<div class="listingblock">
<div class="content">
<pre class="rouge highlight"><code data-lang="c++"><span class="cp">#include</span> <span class="cpf">&lt;boost/hash2/hmac.hpp&gt;</span><span class="cp">
#include</span> <span class="cpf">&lt;boost/hash2/digest.hpp&gt;</span><span class="cp">
</span>
<span class="k">namespace</span> <span class="n">boost</span> <span class="p">{</span>
<span class="k">namespace</span> <span class="n">hash2</span> <span class="p">{</span>
<span class="k">class</span> <span class="nc">sha2_256</span><span class="p">;</span>
<span class="k">class</span> <span class="nc">sha2_224</span><span class="p">;</span>
<span class="k">class</span> <span class="nc">sha2_512</span><span class="p">;</span>
<span class="k">class</span> <span class="nc">sha2_384</span><span class="p">;</span>
<span class="k">class</span> <span class="nc">sha2_512_256</span><span class="p">;</span>
<span class="k">class</span> <span class="nc">sha2_512_224</span><span class="p">;</span>
<span class="k">using</span> <span class="n">hmac_sha2_256</span> <span class="o">=</span> <span class="n">hmac</span><span class="o">&lt;</span><span class="n">sha2_256</span><span class="o">&gt;</span><span class="p">;</span>
<span class="k">using</span> <span class="n">hmac_sha2_224</span> <span class="o">=</span> <span class="n">hmac</span><span class="o">&lt;</span><span class="n">sha2_224</span><span class="o">&gt;</span><span class="p">;</span>
<span class="k">using</span> <span class="n">hmac_sha2_512</span> <span class="o">=</span> <span class="n">hmac</span><span class="o">&lt;</span><span class="n">sha2_512</span><span class="o">&gt;</span><span class="p">;</span>
<span class="k">using</span> <span class="n">hmac_sha2_384</span> <span class="o">=</span> <span class="n">hmac</span><span class="o">&lt;</span><span class="n">sha2_384</span><span class="o">&gt;</span><span class="p">;</span>
<span class="k">using</span> <span class="n">hmac_sha2_512_256</span> <span class="o">=</span> <span class="n">hmac</span><span class="o">&lt;</span><span class="n">sha2_512_256</span><span class="o">&gt;</span><span class="p">;</span>
<span class="k">using</span> <span class="n">hmac_sha2_512_224</span> <span class="o">=</span> <span class="n">hmac</span><span class="o">&lt;</span><span class="n">sha2_512_224</span><span class="o">&gt;</span><span class="p">;</span>
<span class="p">}</span> <span class="c1">// namespace hash2</span>
<span class="p">}</span> <span class="c1">// namespace boost</span></code></pre>
</div>
</div>
<div class="paragraph">
<p>This header implements the <a href="https://csrc.nist.gov/pubs/fips/180-4/upd1/final">SHA-2</a> family of functions.</p>
</div>
<div class="sect4">
<h5 id="ref_sha2_sha2_256">sha2_256</h5>
<div class="listingblock">
<div class="content">
<pre class="rouge highlight"><code data-lang="c++"><span class="k">class</span> <span class="nc">sha2_256</span>
<span class="p">{</span>
<span class="k">using</span> <span class="n">result_type</span> <span class="o">=</span> <span class="n">digest</span><span class="o">&lt;</span><span class="mi">32</span><span class="o">&gt;</span><span class="p">;</span>
<span class="k">static</span> <span class="k">constexpr</span> <span class="kt">int</span> <span class="n">block_size</span> <span class="o">=</span> <span class="mi">64</span><span class="p">;</span>
<span class="k">constexpr</span> <span class="n">sha2_256</span><span class="p">();</span>
<span class="k">constexpr</span> <span class="k">explicit</span> <span class="n">sha2_256</span><span class="p">(</span> <span class="n">std</span><span class="o">::</span><span class="kt">uint64_t</span> <span class="n">seed</span> <span class="p">);</span>
<span class="k">constexpr</span> <span class="n">sha2_256</span><span class="p">(</span> <span class="kt">unsigned</span> <span class="kt">char</span> <span class="k">const</span> <span class="o">*</span> <span class="n">p</span><span class="p">,</span> <span class="n">std</span><span class="o">::</span><span class="kt">size_t</span> <span class="n">n</span> <span class="p">);</span>
<span class="kt">void</span> <span class="n">update</span><span class="p">(</span> <span class="kt">void</span> <span class="k">const</span> <span class="o">*</span> <span class="n">p</span><span class="p">,</span> <span class="n">std</span><span class="o">::</span><span class="kt">size_t</span> <span class="n">n</span> <span class="p">);</span>
<span class="k">constexpr</span> <span class="kt">void</span> <span class="n">update</span><span class="p">(</span> <span class="kt">unsigned</span> <span class="kt">char</span> <span class="k">const</span><span class="o">*</span> <span class="n">p</span><span class="p">,</span> <span class="n">std</span><span class="o">::</span><span class="kt">size_t</span> <span class="n">n</span> <span class="p">);</span>
<span class="k">constexpr</span> <span class="n">result_type</span> <span class="n">result</span><span class="p">();</span>
<span class="p">};</span></code></pre>
</div>
</div>
<div class="sect5">
<h6 id="ref_sha2_constructors">Constructors</h6>
<div class="listingblock">
<div class="content">
<pre class="rouge highlight"><code data-lang="c++"><span class="k">constexpr</span> <span class="nf">sha2_256</span><span class="p">();</span></code></pre>
</div>
</div>
<div class="paragraph">
<p>Default constructor.</p>
</div>
<div class="dlist">
<dl>
<dt class="hdlist1">Effects: </dt>
<dd>
<p>Initializes the internal state of the SHA-256 algorithm to its initial values.</p>
</dd>
</dl>
</div>
<div class="listingblock">
<div class="content">
<pre class="rouge highlight"><code data-lang="c++"><span class="k">constexpr</span> <span class="k">explicit</span> <span class="nf">sha2_256</span><span class="p">(</span> <span class="n">std</span><span class="o">::</span><span class="kt">uint64_t</span> <span class="n">seed</span> <span class="p">);</span></code></pre>
</div>
</div>
<div class="paragraph">
<p>Constructor taking an integer seed value.</p>
</div>
<div class="dlist">
<dl>
<dt class="hdlist1">Effects: </dt>
<dd>
<p>Initializes the state as if by default construction, then if <code>seed</code> is not zero, performs <code>update(p, 8); result();</code> where <code>p</code> points to a little-endian representation of the value of <code>seed</code>.</p>
</dd>
<dt class="hdlist1">Remarks: </dt>
<dd>
<p>By convention, if <code>seed</code> is zero, the effect of this constructor is the same as default construction.</p>
</dd>
</dl>
</div>
<div class="listingblock">
<div class="content">
<pre class="rouge highlight"><code data-lang="c++"><span class="k">constexpr</span> <span class="nf">sha2_256</span><span class="p">(</span> <span class="kt">unsigned</span> <span class="kt">char</span> <span class="k">const</span> <span class="o">*</span> <span class="n">p</span><span class="p">,</span> <span class="n">std</span><span class="o">::</span><span class="kt">size_t</span> <span class="n">n</span> <span class="p">);</span></code></pre>
</div>
</div>
<div class="paragraph">
<p>Constructor taking a byte sequence seed.</p>
</div>
<div class="dlist">
<dl>
<dt class="hdlist1">Effects: </dt>
<dd>
<p>Initializes the state as if by default construction, then if <code>n</code> is not zero, performs <code>update(p, n); result()</code>.</p>
</dd>
<dt class="hdlist1">Remarks: </dt>
<dd>
<p>By convention, if <code>n</code> is zero, the effect of this constructor is the same as default construction.</p>
</dd>
</dl>
</div>
</div>
<div class="sect5">
<h6 id="ref_sha2_update">update</h6>
<div class="listingblock">
<div class="content">
<pre class="rouge highlight"><code data-lang="c++"><span class="kt">void</span> <span class="nf">update</span><span class="p">(</span> <span class="kt">void</span> <span class="k">const</span> <span class="o">*</span> <span class="n">p</span><span class="p">,</span> <span class="n">std</span><span class="o">::</span><span class="kt">size_t</span> <span class="n">n</span> <span class="p">);</span>
<span class="k">constexpr</span> <span class="kt">void</span> <span class="nf">update</span><span class="p">(</span> <span class="kt">unsigned</span> <span class="kt">char</span> <span class="k">const</span><span class="o">*</span> <span class="n">p</span><span class="p">,</span> <span class="n">std</span><span class="o">::</span><span class="kt">size_t</span> <span class="n">n</span> <span class="p">);</span></code></pre>
</div>
</div>
<div class="dlist">
<dl>
<dt class="hdlist1">Effects: </dt>
<dd>
<p>Updates the internal state of the SHA-256 algorithm from the byte sequence <code>[p, p+n)</code>.</p>
</dd>
<dt class="hdlist1">Remarks: </dt>
<dd>
<p>Consecutive calls to <code>update</code> are equivalent to a single call with the concatenated byte sequences of the individual calls.</p>
</dd>
</dl>
</div>
</div>
<div class="sect5">
<h6 id="ref_sha2_result">result</h6>
<div class="listingblock">
<div class="content">
<pre class="rouge highlight"><code data-lang="c++"><span class="k">constexpr</span> <span class="n">result_type</span> <span class="nf">result</span><span class="p">();</span></code></pre>
</div>
</div>
<div class="dlist">
<dl>
<dt class="hdlist1">Effects: </dt>
<dd>
<p>Pads the accumulated message and finalizes the SHA-256 digest.</p>
</dd>
<dt class="hdlist1">Returns: </dt>
<dd>
<p>The SHA-256 digest of the message formed from the byte sequences of the preceding calls to <code>update</code>.</p>
</dd>
<dt class="hdlist1">Remarks: </dt>
<dd>
<p>Repeated calls to <code>result()</code> return a pseudorandom sequence of <code>result_type</code> values, effectively extending the output.</p>
</dd>
</dl>
</div>
</div>
</div>
<div class="sect4">
<h5 id="ref_sha2_sha2_224">sha2_224</h5>
<div class="paragraph">
<p>The SHA-224 algorithm is identical to the SHA-256 algorithm described above.</p>
</div>
<div class="paragraph">
<p>The only differences are the internal state&#8217;s initial values and the size of the message digest, which is:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="rouge highlight"><code data-lang="c++"><span class="k">using</span> <span class="n">result_type</span> <span class="o">=</span> <span class="n">digest</span><span class="o">&lt;</span><span class="mi">28</span><span class="o">&gt;</span><span class="p">;</span></code></pre>
</div>
</div>
<div class="paragraph">
<p>Otherwise, all other operations and constants are identical.</p>
</div>
<div class="paragraph">
<p>The message digest is obtained by truncating the final results of the SHA-256 algorithm to its leftmost 224 bits.</p>
</div>
</div>
<div class="sect4">
<h5 id="ref_sha2_sha2_512">sha2_512</h5>
<div class="listingblock">
<div class="content">
<pre class="rouge highlight"><code data-lang="c++"><span class="k">class</span> <span class="nc">sha2_512</span>
<span class="p">{</span>
<span class="k">using</span> <span class="n">result_type</span> <span class="o">=</span> <span class="n">digest</span><span class="o">&lt;</span><span class="mi">64</span><span class="o">&gt;</span><span class="p">;</span>
<span class="k">static</span> <span class="k">constexpr</span> <span class="kt">int</span> <span class="n">block_size</span> <span class="o">=</span> <span class="mi">128</span><span class="p">;</span>
<span class="k">constexpr</span> <span class="n">sha2_512</span><span class="p">();</span>
<span class="k">constexpr</span> <span class="k">explicit</span> <span class="n">sha2_512</span><span class="p">(</span> <span class="n">std</span><span class="o">::</span><span class="kt">uint64_t</span> <span class="n">seed</span> <span class="p">);</span>
<span class="k">constexpr</span> <span class="n">sha2_512</span><span class="p">(</span> <span class="kt">unsigned</span> <span class="kt">char</span> <span class="k">const</span> <span class="o">*</span> <span class="n">p</span><span class="p">,</span> <span class="n">std</span><span class="o">::</span><span class="kt">size_t</span> <span class="n">n</span> <span class="p">);</span>
<span class="kt">void</span> <span class="n">update</span><span class="p">(</span> <span class="kt">void</span> <span class="k">const</span> <span class="o">*</span> <span class="n">p</span><span class="p">,</span> <span class="n">std</span><span class="o">::</span><span class="kt">size_t</span> <span class="n">n</span> <span class="p">);</span>
<span class="k">constexpr</span> <span class="kt">void</span> <span class="n">update</span><span class="p">(</span> <span class="kt">unsigned</span> <span class="kt">char</span> <span class="k">const</span><span class="o">*</span> <span class="n">p</span><span class="p">,</span> <span class="n">std</span><span class="o">::</span><span class="kt">size_t</span> <span class="n">n</span> <span class="p">);</span>
<span class="k">constexpr</span> <span class="n">result_type</span> <span class="n">result</span><span class="p">();</span>
<span class="p">};</span></code></pre>
</div>
</div>
<div class="sect5">
<h6 id="ref_sha2_constructors_2">Constructors</h6>
<div class="listingblock">
<div class="content">
<pre class="rouge highlight"><code data-lang="c++"><span class="k">constexpr</span> <span class="nf">sha2_512</span><span class="p">();</span></code></pre>
</div>
</div>
<div class="paragraph">
<p>Default constructor.</p>
</div>
<div class="dlist">
<dl>
<dt class="hdlist1">Effects: </dt>
<dd>
<p>Initializes the internal state of the SHA-512 algorithm to its initial values.</p>
</dd>
</dl>
</div>
<div class="listingblock">
<div class="content">
<pre class="rouge highlight"><code data-lang="c++"><span class="k">constexpr</span> <span class="k">explicit</span> <span class="nf">sha2_512</span><span class="p">(</span> <span class="n">std</span><span class="o">::</span><span class="kt">uint64_t</span> <span class="n">seed</span> <span class="p">);</span></code></pre>
</div>
</div>
<div class="paragraph">
<p>Constructor taking an integer seed value.</p>
</div>
<div class="dlist">
<dl>
<dt class="hdlist1">Effects: </dt>
<dd>
<p>Initializes the state as if by default construction, then if <code>seed</code> is not zero, performs <code>update(p, 8); result();</code> where <code>p</code> points to a little-endian representation of the value of <code>seed</code>.</p>
</dd>
<dt class="hdlist1">Remarks: </dt>
<dd>
<p>By convention, if <code>seed</code> is zero, the effect of this constructor is the same as default construction.</p>
</dd>
</dl>
</div>
<div class="listingblock">
<div class="content">
<pre class="rouge highlight"><code data-lang="c++"><span class="k">constexpr</span> <span class="nf">sha2_512</span><span class="p">(</span> <span class="kt">unsigned</span> <span class="kt">char</span> <span class="k">const</span> <span class="o">*</span> <span class="n">p</span><span class="p">,</span> <span class="n">std</span><span class="o">::</span><span class="kt">size_t</span> <span class="n">n</span> <span class="p">);</span></code></pre>
</div>
</div>
<div class="paragraph">
<p>Constructor taking a byte sequence seed.</p>
</div>
<div class="dlist">
<dl>
<dt class="hdlist1">Effects: </dt>
<dd>
<p>Initializes the state as if by default construction, then if <code>n</code> is not zero, performs <code>update(p, n); result()</code>.</p>
</dd>
<dt class="hdlist1">Remarks: </dt>
<dd>
<p>By convention, if <code>n</code> is zero, the effect of this constructor is the same as default construction.</p>
</dd>
</dl>
</div>
</div>
<div class="sect5">
<h6 id="ref_sha2_update_2">update</h6>
<div class="listingblock">
<div class="content">
<pre class="rouge highlight"><code data-lang="c++"><span class="kt">void</span> <span class="nf">update</span><span class="p">(</span> <span class="kt">void</span> <span class="k">const</span> <span class="o">*</span> <span class="n">p</span><span class="p">,</span> <span class="n">std</span><span class="o">::</span><span class="kt">size_t</span> <span class="n">n</span> <span class="p">);</span>
<span class="k">constexpr</span> <span class="kt">void</span> <span class="nf">update</span><span class="p">(</span> <span class="kt">unsigned</span> <span class="kt">char</span> <span class="k">const</span><span class="o">*</span> <span class="n">p</span><span class="p">,</span> <span class="n">std</span><span class="o">::</span><span class="kt">size_t</span> <span class="n">n</span> <span class="p">);</span></code></pre>
</div>
</div>
<div class="dlist">
<dl>
<dt class="hdlist1">Effects: </dt>
<dd>
<p>Updates the internal state of the SHA-512 algorithm from the byte sequence <code>[p, p+n)</code>.</p>
</dd>
<dt class="hdlist1">Remarks: </dt>
<dd>
<p>Consecutive calls to <code>update</code> are equivalent to a single call with the concatenated byte sequences of the individual calls.</p>
</dd>
</dl>
</div>
</div>
<div class="sect5">
<h6 id="ref_sha2_result_2">result</h6>
<div class="listingblock">
<div class="content">
<pre class="rouge highlight"><code data-lang="c++"><span class="k">constexpr</span> <span class="n">result_type</span> <span class="nf">result</span><span class="p">();</span></code></pre>
</div>
</div>
<div class="dlist">
<dl>
<dt class="hdlist1">Effects: </dt>
<dd>
<p>Pads the accumulated message and finalizes the SHA-512 digest.</p>
</dd>
<dt class="hdlist1">Returns: </dt>
<dd>
<p>The SHA-512 digest of the message formed from the byte sequences of the preceding calls to <code>update</code>.</p>
</dd>
<dt class="hdlist1">Remarks: </dt>
<dd>
<p>Repeated calls to <code>result()</code> return a pseudorandom sequence of <code>result_type</code> values, effectively extending the output.</p>
</dd>
</dl>
</div>
</div>
</div>
<div class="sect4">
<h5 id="ref_sha2_sha2_384">sha2_384</h5>
<div class="paragraph">
<p>The SHA-384 algorithm is identical to the SHA-512 algorithm described above.</p>
</div>
<div class="paragraph">
<p>The only differences are the internal state&#8217;s initial values and the size of the message digest, which is:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="rouge highlight"><code data-lang="c++"><span class="k">using</span> <span class="n">result_type</span> <span class="o">=</span> <span class="n">digest</span><span class="o">&lt;</span><span class="mi">48</span><span class="o">&gt;</span><span class="p">;</span></code></pre>
</div>
</div>
<div class="paragraph">
<p>Otherwise, all other operations and constants are identical.</p>
</div>
<div class="paragraph">
<p>The message digest is obtained by truncating the final results of the SHA-512 algorithm to its leftmost 384 bits.</p>
</div>
</div>
<div class="sect4">
<h5 id="ref_sha2_sha2_512_224">sha2_512_224</h5>
<div class="paragraph">
<p>The SHA-512/224 algorithm is identical to the SHA-512 algorithm described above.</p>
</div>
<div class="paragraph">
<p>The only differences are the internal state&#8217;s initial values and the size of the message digest, which is:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="rouge highlight"><code data-lang="c++"><span class="k">using</span> <span class="n">result_type</span> <span class="o">=</span> <span class="n">digest</span><span class="o">&lt;</span><span class="mi">28</span><span class="o">&gt;</span><span class="p">;</span></code></pre>
</div>
</div>
<div class="paragraph">
<p>Otherwise, all other operations and constants are identical.</p>
</div>
<div class="paragraph">
<p>The message digest is obtained by truncating the final results of the SHA-512 algorithm to its leftmost 224 bits.</p>
</div>
</div>
<div class="sect4">
<h5 id="ref_sha2_sha2_512_256">sha2_512_256</h5>
<div class="paragraph">
<p>The SHA-512/256 algorithm is identical to the SHA-512 algorithm described above.</p>
</div>
<div class="paragraph">
<p>The only differences are the internal state&#8217;s initial values and the size of the message digest, which is:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="rouge highlight"><code data-lang="c++"><span class="k">using</span> <span class="n">result_type</span> <span class="o">=</span> <span class="n">digest</span><span class="o">&lt;</span><span class="mi">32</span><span class="o">&gt;</span><span class="p">;</span></code></pre>
</div>
</div>
<div class="paragraph">
<p>Otherwise, all other operations and constants are identical.</p>
</div>
<div class="paragraph">
<p>The message digest is obtained by truncating the final results of the SHA-512 algorithm to its leftmost 256 bits.</p>
</div>
</div>
</div>
<div class="sect3">
<h4 id="ref_ripemd">&lt;boost/hash2/ripemd.hpp&gt;</h4>
<div class="listingblock">
<div class="content">
<pre class="rouge highlight"><code data-lang="c++"><span class="cp">#include</span> <span class="cpf">&lt;boost/hash2/hmac.hpp&gt;</span><span class="cp">
#include</span> <span class="cpf">&lt;boost/hash2/digest.hpp&gt;</span><span class="cp">
</span>
<span class="k">namespace</span> <span class="n">boost</span> <span class="p">{</span>
<span class="k">namespace</span> <span class="n">hash2</span> <span class="p">{</span>
<span class="k">class</span> <span class="nc">ripemd_160</span><span class="p">;</span>
<span class="k">class</span> <span class="nc">ripemd_128</span><span class="p">;</span>
<span class="k">using</span> <span class="n">hmac_ripemd_160</span> <span class="o">=</span> <span class="n">hmac</span><span class="o">&lt;</span><span class="n">ripemd_160</span><span class="o">&gt;</span><span class="p">;</span>
<span class="k">using</span> <span class="n">hmac_ripemd_128</span> <span class="o">=</span> <span class="n">hmac</span><span class="o">&lt;</span><span class="n">ripemd_128</span><span class="o">&gt;</span><span class="p">;</span>
<span class="p">}</span> <span class="c1">// namespace hash2</span>
<span class="p">}</span> <span class="c1">// namespace boost</span></code></pre>
</div>
</div>
<div class="paragraph">
<p>This header implements the <a href="https://homes.esat.kuleuven.be/~bosselae/ripemd160/pdf/AB-9601/AB-9601.pdf">RIPEMD-160 and RIPEMD-128</a> algorithms.</p>
</div>
<div class="sect4">
<h5 id="ref_ripemd_ripemd_160">ripemd_160</h5>
<div class="listingblock">
<div class="content">
<pre class="rouge highlight"><code data-lang="c++"><span class="k">class</span> <span class="nc">ripemd_160</span>
<span class="p">{</span>
<span class="k">using</span> <span class="n">result_type</span> <span class="o">=</span> <span class="n">digest</span><span class="o">&lt;</span><span class="mi">20</span><span class="o">&gt;</span><span class="p">;</span>
<span class="k">static</span> <span class="k">constexpr</span> <span class="kt">int</span> <span class="n">block_size</span> <span class="o">=</span> <span class="mi">64</span><span class="p">;</span>
<span class="k">constexpr</span> <span class="n">ripemd_160</span><span class="p">();</span>
<span class="k">explicit</span> <span class="k">constexpr</span> <span class="n">ripemd_160</span><span class="p">(</span> <span class="n">std</span><span class="o">::</span><span class="kt">uint64_t</span> <span class="n">seed</span> <span class="p">);</span>
<span class="k">constexpr</span> <span class="n">ripemd_160</span><span class="p">(</span> <span class="kt">unsigned</span> <span class="kt">char</span> <span class="k">const</span><span class="o">*</span> <span class="n">p</span><span class="p">,</span> <span class="n">std</span><span class="o">::</span><span class="kt">size_t</span> <span class="n">n</span> <span class="p">);</span>
<span class="kt">void</span> <span class="n">update</span><span class="p">(</span> <span class="kt">void</span> <span class="k">const</span> <span class="o">*</span> <span class="n">pv</span><span class="p">,</span> <span class="n">std</span><span class="o">::</span><span class="kt">size_t</span> <span class="n">n</span> <span class="p">);</span>
<span class="k">constexpr</span> <span class="kt">void</span> <span class="n">update</span><span class="p">(</span> <span class="kt">unsigned</span> <span class="kt">char</span> <span class="k">const</span><span class="o">*</span> <span class="n">p</span><span class="p">,</span> <span class="n">std</span><span class="o">::</span><span class="kt">size_t</span> <span class="n">n</span> <span class="p">);</span>
<span class="k">constexpr</span> <span class="n">result_type</span> <span class="n">result</span><span class="p">();</span>
<span class="p">};</span></code></pre>
</div>
</div>
<div class="sect5">
<h6 id="ref_ripemd_constructors">Constructors</h6>
<div class="listingblock">
<div class="content">
<pre class="rouge highlight"><code data-lang="c++"><span class="k">constexpr</span> <span class="nf">ripemd_160</span><span class="p">();</span></code></pre>
</div>
</div>
<div class="paragraph">
<p>Default constructor.</p>
</div>
<div class="dlist">
<dl>
<dt class="hdlist1">Effects: </dt>
<dd>
<p>Initializes the internal state of the RIPEMD-160 algorithm to its initial values.</p>
</dd>
</dl>
</div>
<div class="listingblock">
<div class="content">
<pre class="rouge highlight"><code data-lang="c++"><span class="k">explicit</span> <span class="k">constexpr</span> <span class="nf">ripemd_160</span><span class="p">(</span> <span class="n">std</span><span class="o">::</span><span class="kt">uint64_t</span> <span class="n">seed</span> <span class="p">);</span></code></pre>
</div>
</div>
<div class="paragraph">
<p>Constructor taking an integer seed value.</p>
</div>
<div class="dlist">
<dl>
<dt class="hdlist1">Effects: </dt>
<dd>
<p>Initializes the state as if by default construction, then if <code>seed</code> is not zero, performs <code>update(p, 8); result();</code> where <code>p</code> points to a little-endian representation of the value of <code>seed</code>.</p>
</dd>
<dt class="hdlist1">Remarks: </dt>
<dd>
<p>By convention, if <code>seed</code> is zero, the effect of this constructor is the same as default construction.</p>
</dd>
</dl>
</div>
<div class="listingblock">
<div class="content">
<pre class="rouge highlight"><code data-lang="c++"><span class="k">constexpr</span> <span class="nf">ripemd_160</span><span class="p">(</span> <span class="kt">unsigned</span> <span class="kt">char</span> <span class="k">const</span><span class="o">*</span> <span class="n">p</span><span class="p">,</span> <span class="n">std</span><span class="o">::</span><span class="kt">size_t</span> <span class="n">n</span> <span class="p">);</span></code></pre>
</div>
</div>
<div class="paragraph">
<p>Constructor taking a byte sequence seed.</p>
</div>
<div class="dlist">
<dl>
<dt class="hdlist1">Effects: </dt>
<dd>
<p>Initializes the state as if by default construction, then if <code>n</code> is not zero, performs <code>update(p, n); result()</code>.</p>
</dd>
<dt class="hdlist1">Remarks: </dt>
<dd>
<p>By convention, if <code>n</code> is zero, the effect of this constructor is the same as default construction.</p>
</dd>
</dl>
</div>
</div>
<div class="sect5">
<h6 id="ref_ripemd_update">update</h6>
<div class="listingblock">
<div class="content">
<pre class="rouge highlight"><code data-lang="c++"><span class="kt">void</span> <span class="nf">update</span><span class="p">(</span> <span class="kt">void</span> <span class="k">const</span><span class="o">*</span> <span class="n">p</span><span class="p">,</span> <span class="n">std</span><span class="o">::</span><span class="kt">size_t</span> <span class="n">n</span> <span class="p">);</span>
<span class="k">constexpr</span> <span class="kt">void</span> <span class="nf">update</span><span class="p">(</span> <span class="kt">unsigned</span> <span class="kt">char</span> <span class="k">const</span><span class="o">*</span> <span class="n">p</span><span class="p">,</span> <span class="n">std</span><span class="o">::</span><span class="kt">size_t</span> <span class="n">n</span> <span class="p">);</span></code></pre>
</div>
</div>
<div class="dlist">
<dl>
<dt class="hdlist1">Effects: </dt>
<dd>
<p>Updates the internal state of the RIPEMD-160 algorithm from the byte sequence <code>[p, p+n)</code>.</p>
</dd>
<dt class="hdlist1">Remarks: </dt>
<dd>
<p>Consecutive calls to <code>update</code> are equivalent to a single call with the concatenated byte sequences of the individual calls.</p>
</dd>
</dl>
</div>
</div>
<div class="sect5">
<h6 id="ref_ripemd_result">result</h6>
<div class="listingblock">
<div class="content">
<pre class="rouge highlight"><code data-lang="c++"><span class="k">constexpr</span> <span class="n">result_type</span> <span class="nf">result</span><span class="p">();</span></code></pre>
</div>
</div>
<div class="dlist">
<dl>
<dt class="hdlist1">Effects: </dt>
<dd>
<p>Pads the accumulated message and finalizes the RIPEMD-160 digest.</p>
</dd>
<dt class="hdlist1">Returns: </dt>
<dd>
<p>The RIPEMD-160 digest of the message formed from the byte sequences of the preceding calls to <code>update</code>.</p>
</dd>
<dt class="hdlist1">Remarks: </dt>
<dd>
<p>Repeated calls to <code>result()</code> return a pseudorandom sequence of <code>result_type</code> values, effectively extending the output.</p>
</dd>
</dl>
</div>
</div>
</div>
<div class="sect4">
<h5 id="ref_ripemd_ripemd_128">ripemd_128</h5>
<div class="paragraph">
<p>The RIPEMD-128 algorithm is identical to the RIPEMD-160 algorithm described above.</p>
</div>
<div class="paragraph">
<p>The only differences are the number of rounds used and the size of the message digest, which is:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="rouge highlight"><code data-lang="c++"><span class="k">using</span> <span class="n">result_type</span> <span class="o">=</span> <span class="n">digest</span><span class="o">&lt;</span><span class="mi">16</span><span class="o">&gt;</span><span class="p">;</span></code></pre>
</div>
</div>
<div class="paragraph">
<p>Otherwise, all other operations and constants are identical.</p>
</div>
</div>
</div>
</div>
<div class="sect2">
<h3 id="ref_utilities_and_traits">Utilities and Traits</h3>
<div class="sect3">
<h4 id="ref_digest">&lt;boost/hash2/digest.hpp&gt;</h4>
<div class="listingblock">
<div class="content">
<pre class="rouge highlight"><code data-lang="c++"><span class="k">namespace</span> <span class="n">boost</span> <span class="p">{</span>
<span class="k">namespace</span> <span class="n">hash2</span> <span class="p">{</span>
<span class="k">template</span><span class="o">&lt;</span><span class="n">std</span><span class="o">::</span><span class="kt">size_t</span> <span class="n">N</span><span class="p">&gt;</span> <span class="k">class</span> <span class="nc">digest</span>
<span class="p">{</span>
<span class="nl">private:</span> <span class="c1">// exposition only</span>
<span class="kt">unsigned</span> <span class="kt">char</span> <span class="n">data_</span><span class="p">[</span> <span class="n">N</span> <span class="p">]</span> <span class="o">=</span> <span class="p">{};</span>
<span class="nl">public:</span>
<span class="k">using</span> <span class="n">value_type</span> <span class="o">=</span> <span class="kt">unsigned</span> <span class="kt">char</span><span class="p">;</span>
<span class="k">using</span> <span class="n">reference</span> <span class="o">=</span> <span class="kt">unsigned</span> <span class="kt">char</span><span class="o">&amp;</span><span class="p">;</span>
<span class="k">using</span> <span class="n">const_reference</span> <span class="o">=</span> <span class="kt">unsigned</span> <span class="kt">char</span> <span class="k">const</span><span class="o">&amp;</span><span class="p">;</span>
<span class="k">using</span> <span class="n">iterator</span> <span class="o">=</span> <span class="kt">unsigned</span> <span class="kt">char</span><span class="o">*</span><span class="p">;</span>
<span class="k">using</span> <span class="n">const_iterator</span> <span class="o">=</span> <span class="kt">unsigned</span> <span class="kt">char</span> <span class="k">const</span><span class="o">*</span><span class="p">;</span>
<span class="k">using</span> <span class="n">size_type</span> <span class="o">=</span> <span class="n">std</span><span class="o">::</span><span class="kt">size_t</span><span class="p">;</span>
<span class="k">using</span> <span class="n">difference_type</span> <span class="o">=</span> <span class="n">std</span><span class="o">::</span><span class="kt">ptrdiff_t</span><span class="p">;</span>
<span class="c1">// constructors</span>
<span class="k">constexpr</span> <span class="n">digest</span><span class="p">()</span> <span class="o">=</span> <span class="k">default</span><span class="p">;</span>
<span class="k">constexpr</span> <span class="n">digest</span><span class="p">(</span> <span class="kt">unsigned</span> <span class="kt">char</span> <span class="k">const</span> <span class="p">(</span><span class="o">&amp;</span><span class="n">v</span><span class="p">)[</span> <span class="n">N</span> <span class="p">]</span> <span class="p">)</span> <span class="k">noexcept</span><span class="p">;</span>
<span class="c1">// copy</span>
<span class="k">constexpr</span> <span class="n">digest</span><span class="p">(</span> <span class="n">digest</span> <span class="k">const</span><span class="o">&amp;</span> <span class="p">)</span> <span class="o">=</span> <span class="k">default</span><span class="p">;</span>
<span class="k">constexpr</span> <span class="n">digest</span><span class="o">&amp;</span> <span class="k">operator</span><span class="o">=</span><span class="p">(</span> <span class="n">digest</span> <span class="k">const</span><span class="o">&amp;</span> <span class="p">)</span> <span class="o">=</span> <span class="k">default</span><span class="p">;</span>
<span class="c1">// iteration</span>
<span class="k">constexpr</span> <span class="n">iterator</span> <span class="n">begin</span><span class="p">()</span> <span class="k">noexcept</span><span class="p">;</span>
<span class="k">constexpr</span> <span class="n">const_iterator</span> <span class="n">begin</span><span class="p">()</span> <span class="k">const</span> <span class="k">noexcept</span><span class="p">;</span>
<span class="k">constexpr</span> <span class="n">iterator</span> <span class="n">end</span><span class="p">()</span> <span class="k">noexcept</span><span class="p">;</span>
<span class="k">constexpr</span> <span class="n">const_iterator</span> <span class="n">end</span><span class="p">()</span> <span class="k">const</span> <span class="k">noexcept</span><span class="p">;</span>
<span class="c1">// data, size</span>
<span class="k">constexpr</span> <span class="kt">unsigned</span> <span class="kt">char</span><span class="o">*</span> <span class="n">data</span><span class="p">()</span> <span class="k">noexcept</span><span class="p">;</span>
<span class="k">constexpr</span> <span class="kt">unsigned</span> <span class="kt">char</span> <span class="k">const</span><span class="o">*</span> <span class="n">data</span><span class="p">()</span> <span class="k">const</span> <span class="k">noexcept</span><span class="p">;</span>
<span class="k">constexpr</span> <span class="n">size_type</span> <span class="n">size</span><span class="p">()</span> <span class="k">const</span> <span class="k">noexcept</span><span class="p">;</span>
<span class="k">constexpr</span> <span class="n">size_type</span> <span class="n">max_size</span><span class="p">()</span> <span class="k">const</span> <span class="k">noexcept</span><span class="p">;</span>
<span class="c1">// element access</span>
<span class="k">constexpr</span> <span class="n">reference</span> <span class="k">operator</span><span class="p">[](</span> <span class="n">std</span><span class="o">::</span><span class="kt">size_t</span> <span class="n">i</span> <span class="p">);</span>
<span class="k">constexpr</span> <span class="n">const_reference</span> <span class="k">operator</span><span class="p">[](</span> <span class="n">std</span><span class="o">::</span><span class="kt">size_t</span> <span class="n">i</span> <span class="p">)</span> <span class="k">const</span><span class="p">;</span>
<span class="k">constexpr</span> <span class="n">reference</span> <span class="n">front</span><span class="p">()</span> <span class="k">noexcept</span><span class="p">;</span>
<span class="k">constexpr</span> <span class="n">const_reference</span> <span class="n">front</span><span class="p">()</span> <span class="k">const</span> <span class="k">noexcept</span><span class="p">;</span>
<span class="k">constexpr</span> <span class="n">reference</span> <span class="n">back</span><span class="p">()</span> <span class="k">noexcept</span><span class="p">;</span>
<span class="k">constexpr</span> <span class="n">const_reference</span> <span class="n">back</span><span class="p">()</span> <span class="k">const</span> <span class="k">noexcept</span><span class="p">;</span>
<span class="p">};</span>
<span class="c1">// comparisons</span>
<span class="k">template</span><span class="o">&lt;</span><span class="n">std</span><span class="o">::</span><span class="kt">size_t</span> <span class="n">N</span><span class="p">&gt;</span>
<span class="k">constexpr</span> <span class="kt">bool</span> <span class="k">operator</span><span class="o">==</span><span class="p">(</span> <span class="n">digest</span><span class="o">&lt;</span><span class="n">N</span><span class="o">&gt;</span> <span class="k">const</span><span class="o">&amp;</span> <span class="n">a</span><span class="p">,</span> <span class="n">digest</span><span class="o">&lt;</span><span class="n">N</span><span class="o">&gt;</span> <span class="k">const</span><span class="o">&amp;</span> <span class="n">b</span> <span class="p">)</span> <span class="k">noexcept</span><span class="p">;</span>
<span class="k">template</span><span class="o">&lt;</span><span class="n">std</span><span class="o">::</span><span class="kt">size_t</span> <span class="n">N</span><span class="p">&gt;</span>
<span class="k">constexpr</span> <span class="kt">bool</span> <span class="k">operator</span><span class="o">!=</span><span class="p">(</span> <span class="n">digest</span><span class="o">&lt;</span><span class="n">N</span><span class="o">&gt;</span> <span class="k">const</span><span class="o">&amp;</span> <span class="n">a</span><span class="p">,</span> <span class="n">digest</span><span class="o">&lt;</span><span class="n">N</span><span class="o">&gt;</span> <span class="k">const</span><span class="o">&amp;</span> <span class="n">b</span> <span class="p">)</span> <span class="k">noexcept</span><span class="p">;</span>
<span class="c1">// to_chars</span>
<span class="k">template</span><span class="o">&lt;</span><span class="n">std</span><span class="o">::</span><span class="kt">size_t</span> <span class="n">N</span><span class="p">&gt;</span>
<span class="k">constexpr</span> <span class="kt">char</span><span class="o">*</span> <span class="n">to_chars</span><span class="p">(</span> <span class="n">digest</span><span class="o">&lt;</span><span class="n">N</span><span class="o">&gt;</span> <span class="k">const</span><span class="o">&amp;</span> <span class="n">v</span><span class="p">,</span> <span class="kt">char</span><span class="o">*</span> <span class="n">first</span><span class="p">,</span> <span class="kt">char</span><span class="o">*</span> <span class="n">last</span> <span class="p">)</span> <span class="k">noexcept</span><span class="p">;</span>
<span class="k">template</span><span class="o">&lt;</span><span class="n">std</span><span class="o">::</span><span class="kt">size_t</span> <span class="n">N</span><span class="p">,</span> <span class="n">std</span><span class="o">::</span><span class="kt">size_t</span> <span class="n">M</span><span class="p">&gt;</span>
<span class="k">constexpr</span> <span class="kt">void</span> <span class="n">to_chars</span><span class="p">(</span> <span class="n">digest</span><span class="o">&lt;</span><span class="n">N</span><span class="o">&gt;</span> <span class="k">const</span><span class="o">&amp;</span> <span class="n">v</span><span class="p">,</span> <span class="kt">char</span> <span class="p">(</span><span class="o">&amp;</span><span class="n">w</span><span class="p">)[</span> <span class="n">M</span> <span class="p">]</span> <span class="p">)</span> <span class="k">noexcept</span><span class="p">;</span>
<span class="c1">// operator&lt;&lt;</span>
<span class="k">template</span><span class="o">&lt;</span><span class="n">std</span><span class="o">::</span><span class="kt">size_t</span> <span class="n">N</span><span class="p">&gt;</span>
<span class="n">std</span><span class="o">::</span><span class="n">ostream</span><span class="o">&amp;</span> <span class="k">operator</span><span class="o">&lt;&lt;</span><span class="p">(</span> <span class="n">std</span><span class="o">::</span><span class="n">ostream</span><span class="o">&amp;</span> <span class="n">os</span><span class="p">,</span> <span class="n">digest</span><span class="o">&lt;</span><span class="n">N</span><span class="o">&gt;</span> <span class="k">const</span><span class="o">&amp;</span> <span class="n">v</span> <span class="p">);</span>
<span class="c1">// to_string</span>
<span class="k">template</span><span class="o">&lt;</span><span class="n">std</span><span class="o">::</span><span class="kt">size_t</span> <span class="n">N</span><span class="p">&gt;</span>
<span class="n">std</span><span class="o">::</span><span class="n">string</span> <span class="n">to_string</span><span class="p">(</span> <span class="n">digest</span><span class="o">&lt;</span><span class="n">N</span><span class="o">&gt;</span> <span class="k">const</span><span class="o">&amp;</span> <span class="n">v</span> <span class="p">);</span>
<span class="p">}</span> <span class="c1">// namespace hash2</span>
<span class="p">}</span> <span class="c1">// namespace boost</span></code></pre>
</div>
</div>
<div class="sect4">
<h5 id="ref_digest_digest">digest</h5>
<div class="paragraph">
<p><code>digest&lt;N&gt;</code> is a <code>constexpr</code>-friendly class template similar to <code>std::array&lt;unsigned char, N&gt;</code>.
It is used to store the resulting message digest of hash algorithms such as SHA2-256 or RIPEMD-160.</p>
</div>
<div class="sect5">
<h6 id="ref_digest_constructors">Constructors</h6>
<div class="listingblock">
<div class="content">
<pre class="rouge highlight"><code data-lang="c++"><span class="k">constexpr</span> <span class="n">digest</span><span class="p">()</span> <span class="o">=</span> <span class="k">default</span><span class="p">;</span></code></pre>
</div>
</div>
<div class="dlist">
<dl>
<dt class="hdlist1">Effects: </dt>
<dd>
<p>Zero-initializes <code>data_</code>.</p>
</dd>
</dl>
</div>
<div class="listingblock">
<div class="content">
<pre class="rouge highlight"><code data-lang="c++"><span class="k">constexpr</span> <span class="n">digest</span><span class="p">(</span> <span class="kt">unsigned</span> <span class="kt">char</span> <span class="k">const</span> <span class="p">(</span><span class="o">&amp;</span><span class="n">v</span><span class="p">)[</span> <span class="n">N</span> <span class="p">]</span> <span class="p">)</span> <span class="k">noexcept</span><span class="p">;</span></code></pre>
</div>
</div>
<div class="dlist">
<dl>
<dt class="hdlist1">Effects: </dt>
<dd>
<p>Initializes the elements of <code>data_</code> from the corresponding elements of <code>v</code>.</p>
</dd>
</dl>
</div>
</div>
<div class="sect5">
<h6 id="ref_digest_iteration">Iteration</h6>
<div class="listingblock">
<div class="content">
<pre class="rouge highlight"><code data-lang="c++"><span class="k">constexpr</span> <span class="n">iterator</span> <span class="n">begin</span><span class="p">()</span> <span class="k">noexcept</span><span class="p">;</span>
<span class="k">constexpr</span> <span class="n">const_iterator</span> <span class="n">begin</span><span class="p">()</span> <span class="k">const</span> <span class="k">noexcept</span><span class="p">;</span></code></pre>
</div>
</div>
<div class="dlist">
<dl>
<dt class="hdlist1">Returns: </dt>
<dd>
<p><code>data_</code>.</p>
</dd>
</dl>
</div>
<div class="listingblock">
<div class="content">
<pre class="rouge highlight"><code data-lang="c++"><span class="k">constexpr</span> <span class="n">iterator</span> <span class="n">end</span><span class="p">()</span> <span class="k">noexcept</span><span class="p">;</span>
<span class="k">constexpr</span> <span class="n">const_iterator</span> <span class="n">end</span><span class="p">()</span> <span class="k">const</span> <span class="k">noexcept</span><span class="p">;</span></code></pre>
</div>
</div>
<div class="dlist">
<dl>
<dt class="hdlist1">Returns: </dt>
<dd>
<p><code>data_ + N</code>.</p>
</dd>
</dl>
</div>
</div>
<div class="sect5">
<h6 id="ref_digest_accessors">Accessors</h6>
<div class="listingblock">
<div class="content">
<pre class="rouge highlight"><code data-lang="c++"><span class="k">constexpr</span> <span class="kt">unsigned</span> <span class="kt">char</span><span class="o">*</span> <span class="n">data</span><span class="p">()</span> <span class="k">noexcept</span><span class="p">;</span>
<span class="k">constexpr</span> <span class="kt">unsigned</span> <span class="kt">char</span> <span class="k">const</span><span class="o">*</span> <span class="n">data</span><span class="p">()</span> <span class="k">const</span> <span class="k">noexcept</span><span class="p">;</span></code></pre>
</div>
</div>
<div class="dlist">
<dl>
<dt class="hdlist1">Returns: </dt>
<dd>
<p><code>data_</code>.</p>
</dd>
</dl>
</div>
<div class="listingblock">
<div class="content">
<pre class="rouge highlight"><code data-lang="c++"><span class="k">constexpr</span> <span class="n">size_type</span> <span class="n">size</span><span class="p">()</span> <span class="k">const</span> <span class="k">noexcept</span><span class="p">;</span>
<span class="k">constexpr</span> <span class="n">size_type</span> <span class="n">max_size</span><span class="p">()</span> <span class="k">const</span> <span class="k">noexcept</span><span class="p">;</span></code></pre>
</div>
</div>
<div class="dlist">
<dl>
<dt class="hdlist1">Returns: </dt>
<dd>
<p><code>N</code>.</p>
</dd>
</dl>
</div>
</div>
<div class="sect5">
<h6 id="ref_digest_element_access">Element Access</h6>
<div class="listingblock">
<div class="content">
<pre class="rouge highlight"><code data-lang="c++"><span class="k">constexpr</span> <span class="n">reference</span> <span class="k">operator</span><span class="p">[](</span> <span class="n">std</span><span class="o">::</span><span class="kt">size_t</span> <span class="n">i</span> <span class="p">);</span>
<span class="k">constexpr</span> <span class="n">const_reference</span> <span class="k">operator</span><span class="p">[](</span> <span class="n">std</span><span class="o">::</span><span class="kt">size_t</span> <span class="n">i</span> <span class="p">)</span> <span class="k">const</span><span class="p">;</span></code></pre>
</div>
</div>
<div class="dlist">
<dl>
<dt class="hdlist1">Requires: </dt>
<dd>
<p><code>i &lt; size()</code>.</p>
</dd>
<dt class="hdlist1">Returns: </dt>
<dd>
<p><code>data_[ i ]</code>.</p>
</dd>
</dl>
</div>
<div class="listingblock">
<div class="content">
<pre class="rouge highlight"><code data-lang="c++"><span class="k">constexpr</span> <span class="n">reference</span> <span class="n">front</span><span class="p">()</span> <span class="k">noexcept</span><span class="p">;</span>
<span class="k">constexpr</span> <span class="n">const_reference</span> <span class="n">front</span><span class="p">()</span> <span class="k">const</span> <span class="k">noexcept</span><span class="p">;</span></code></pre>
</div>
</div>
<div class="dlist">
<dl>
<dt class="hdlist1">Returns: </dt>
<dd>
<p><code>data_[ 0 ]</code>.</p>
</dd>
</dl>
</div>
<div class="listingblock">
<div class="content">
<pre class="rouge highlight"><code data-lang="c++"><span class="k">constexpr</span> <span class="n">reference</span> <span class="n">back</span><span class="p">()</span> <span class="k">noexcept</span><span class="p">;</span>
<span class="k">constexpr</span> <span class="n">const_reference</span> <span class="n">back</span><span class="p">()</span> <span class="k">const</span> <span class="k">noexcept</span><span class="p">;</span></code></pre>
</div>
</div>
<div class="dlist">
<dl>
<dt class="hdlist1">Returns: </dt>
<dd>
<p><code>data_[ N-1 ]</code>.</p>
</dd>
</dl>
</div>
</div>
<div class="sect5">
<h6 id="ref_digest_comparisons">Comparisons</h6>
<div class="listingblock">
<div class="content">
<pre class="rouge highlight"><code data-lang="c++"><span class="k">template</span><span class="o">&lt;</span><span class="n">std</span><span class="o">::</span><span class="kt">size_t</span> <span class="n">N</span><span class="p">&gt;</span>
<span class="k">constexpr</span> <span class="kt">bool</span> <span class="k">operator</span><span class="o">==</span><span class="p">(</span> <span class="n">digest</span><span class="o">&lt;</span><span class="n">N</span><span class="o">&gt;</span> <span class="k">const</span><span class="o">&amp;</span> <span class="n">a</span><span class="p">,</span> <span class="n">digest</span><span class="o">&lt;</span><span class="n">N</span><span class="o">&gt;</span> <span class="k">const</span><span class="o">&amp;</span> <span class="n">b</span> <span class="p">)</span> <span class="k">noexcept</span><span class="p">;</span></code></pre>
</div>
</div>
<div class="dlist">
<dl>
<dt class="hdlist1">Returns: </dt>
<dd>
<p><code>true</code> when the elements of <code>a.data_</code> are equal to the corresponding elements of <code>b.data_</code>, <code>false</code> otherwise.</p>
</dd>
</dl>
</div>
<div class="listingblock">
<div class="content">
<pre class="rouge highlight"><code data-lang="c++"><span class="k">template</span><span class="o">&lt;</span><span class="n">std</span><span class="o">::</span><span class="kt">size_t</span> <span class="n">N</span><span class="p">&gt;</span>
<span class="k">constexpr</span> <span class="kt">bool</span> <span class="k">operator</span><span class="o">!=</span><span class="p">(</span> <span class="n">digest</span><span class="o">&lt;</span><span class="n">N</span><span class="o">&gt;</span> <span class="k">const</span><span class="o">&amp;</span> <span class="n">a</span><span class="p">,</span> <span class="n">digest</span><span class="o">&lt;</span><span class="n">N</span><span class="o">&gt;</span> <span class="k">const</span><span class="o">&amp;</span> <span class="n">b</span> <span class="p">)</span> <span class="k">noexcept</span><span class="p">;</span></code></pre>
</div>
</div>
<div class="dlist">
<dl>
<dt class="hdlist1">Returns: </dt>
<dd>
<p><code>!(a == b)</code>.</p>
</dd>
</dl>
</div>
</div>
<div class="sect5">
<h6 id="ref_digest_formatting">Formatting</h6>
<div class="listingblock">
<div class="content">
<pre class="rouge highlight"><code data-lang="c++"><span class="k">template</span><span class="o">&lt;</span><span class="n">std</span><span class="o">::</span><span class="kt">size_t</span> <span class="n">N</span><span class="p">&gt;</span>
<span class="k">constexpr</span> <span class="kt">char</span><span class="o">*</span> <span class="n">to_chars</span><span class="p">(</span> <span class="n">digest</span><span class="o">&lt;</span><span class="n">N</span><span class="o">&gt;</span> <span class="k">const</span><span class="o">&amp;</span> <span class="n">v</span><span class="p">,</span> <span class="kt">char</span><span class="o">*</span> <span class="n">first</span><span class="p">,</span> <span class="kt">char</span><span class="o">*</span> <span class="n">last</span> <span class="p">)</span> <span class="k">noexcept</span><span class="p">;</span></code></pre>
</div>
</div>
<div class="dlist">
<dl>
<dt class="hdlist1">Effects: </dt>
<dd>
<p>Writes the contents of <code>data_</code> as a hexadecimal string to the provided output range <code>[first, last)</code>.</p>
</dd>
<dt class="hdlist1">Returns: </dt>
<dd>
<p>A pointer one past the end of the generated output, or <code>nullptr</code> if <code>[first, last)</code> is not large enough.</p>
</dd>
</dl>
</div>
<div class="listingblock">
<div class="content">
<pre class="rouge highlight"><code data-lang="c++"><span class="k">template</span><span class="o">&lt;</span><span class="n">std</span><span class="o">::</span><span class="kt">size_t</span> <span class="n">N</span><span class="p">,</span> <span class="n">std</span><span class="o">::</span><span class="kt">size_t</span> <span class="n">M</span><span class="p">&gt;</span>
<span class="k">constexpr</span> <span class="kt">void</span> <span class="n">to_chars</span><span class="p">(</span> <span class="n">digest</span><span class="o">&lt;</span><span class="n">N</span><span class="o">&gt;</span> <span class="k">const</span><span class="o">&amp;</span> <span class="n">v</span><span class="p">,</span> <span class="kt">char</span> <span class="p">(</span><span class="o">&amp;</span><span class="n">w</span><span class="p">)[</span> <span class="n">M</span> <span class="p">]</span> <span class="p">)</span> <span class="k">noexcept</span><span class="p">;</span></code></pre>
</div>
</div>
<div class="dlist">
<dl>
<dt class="hdlist1">Requires: </dt>
<dd>
<p><code>M &gt;= N*2 + 1</code>.</p>
</dd>
<dt class="hdlist1">Effects: </dt>
<dd>
<p>Writes the contents of <code>data_</code> as a hexadecimal string, then a null terminator, to the provided output buffer <code>w</code>.</p>
</dd>
</dl>
</div>
<div class="listingblock">
<div class="content">
<pre class="rouge highlight"><code data-lang="c++"><span class="k">template</span><span class="o">&lt;</span><span class="n">std</span><span class="o">::</span><span class="kt">size_t</span> <span class="n">N</span><span class="p">&gt;</span>
<span class="n">std</span><span class="o">::</span><span class="n">ostream</span><span class="o">&amp;</span> <span class="k">operator</span><span class="o">&lt;&lt;</span><span class="p">(</span> <span class="n">std</span><span class="o">::</span><span class="n">ostream</span><span class="o">&amp;</span> <span class="n">os</span><span class="p">,</span> <span class="n">digest</span><span class="o">&lt;</span><span class="n">N</span><span class="o">&gt;</span> <span class="k">const</span><span class="o">&amp;</span> <span class="n">v</span> <span class="p">);</span></code></pre>
</div>
</div>
<div class="dlist">
<dl>
<dt class="hdlist1">Effects: </dt>
<dd>
<p>Writes the contents of <code>data_</code> as a hexadecimal string to <code>os</code>.</p>
</dd>
<dt class="hdlist1">Returns: </dt>
<dd>
<p><code>os</code>.</p>
</dd>
</dl>
</div>
<div class="listingblock">
<div class="content">
<pre class="rouge highlight"><code data-lang="c++"><span class="k">template</span><span class="o">&lt;</span><span class="n">std</span><span class="o">::</span><span class="kt">size_t</span> <span class="n">N</span><span class="p">&gt;</span>
<span class="n">std</span><span class="o">::</span><span class="n">string</span> <span class="nf">to_string</span><span class="p">(</span> <span class="n">digest</span><span class="o">&lt;</span><span class="n">N</span><span class="o">&gt;</span> <span class="k">const</span><span class="o">&amp;</span> <span class="n">v</span> <span class="p">);</span></code></pre>
</div>
</div>
<div class="dlist">
<dl>
<dt class="hdlist1">Returns: </dt>
<dd>
<p>A string containing the contents of <code>data_</code> in hexadecimal format.</p>
</dd>
</dl>
</div>
</div>
</div>
</div>
<div class="sect3">
<h4 id="ref_endian">&lt;boost/hash2/endian.hpp&gt;</h4>
<div class="listingblock">
<div class="content">
<pre class="rouge highlight"><code data-lang="c++"><span class="k">namespace</span> <span class="n">boost</span> <span class="p">{</span>
<span class="k">namespace</span> <span class="n">hash2</span> <span class="p">{</span>
<span class="k">enum</span> <span class="k">class</span> <span class="nc">endian</span><span class="p">;</span>
<span class="p">}</span> <span class="c1">// namespace hash2</span>
<span class="p">}</span> <span class="c1">// namespace boost</span></code></pre>
</div>
</div>
<div class="sect4">
<h5 id="ref_endian_endian">endian</h5>
<div class="listingblock">
<div class="content">
<pre class="rouge highlight"><code data-lang="c++"><span class="k">enum</span> <span class="k">class</span> <span class="nc">endian</span>
<span class="p">{</span>
<span class="n">little</span> <span class="o">=</span> <span class="cm">/*...*/</span><span class="p">,</span>
<span class="n">big</span> <span class="o">=</span> <span class="cm">/*...*/</span><span class="p">,</span>
<span class="n">native</span> <span class="o">=</span> <span class="cm">/*little or big*/</span>
<span class="p">};</span></code></pre>
</div>
</div>
<div class="paragraph">
<p>The enumeration type <code>endian</code> corresponds to the standard
<code>std::endian</code> type from C&#43;&#43;20. Its values are <code>little</code>,
signifying little-endian byte order, <code>big</code>, signifying
big-endian byte order, and <code>native</code>, which equals either
<code>little</code> or <code>big</code> depending on whether the current platform
is little- or big-endian.</p>
</div>
<div class="paragraph">
<p>Unlike <code>std::endian</code>, platforms where <code>little</code> equals <code>big</code>,
or where <code>native</code> equals neither <code>little</code> or <code>big</code>, aren&#8217;t
supported.</p>
</div>
</div>
</div>
<div class="sect3">
<h4 id="ref_flavor">&lt;boost/hash2/flavor.hpp&gt;</h4>
<div class="listingblock">
<div class="content">
<pre class="rouge highlight"><code data-lang="c++"><span class="cp">#include</span> <span class="cpf">&lt;boost/hash2/endian.hpp&gt;</span><span class="cp">
</span>
<span class="k">namespace</span> <span class="n">boost</span> <span class="p">{</span>
<span class="k">namespace</span> <span class="n">hash2</span> <span class="p">{</span>
<span class="k">struct</span> <span class="nc">default_flavor</span><span class="p">;</span>
<span class="k">struct</span> <span class="nc">little_endian_flavor</span><span class="p">;</span>
<span class="k">struct</span> <span class="nc">big_endian_flavor</span><span class="p">;</span>
<span class="p">}</span> <span class="c1">// namespace hash2</span>
<span class="p">}</span> <span class="c1">// namespace boost</span></code></pre>
</div>
</div>
<div class="sect4">
<h5 id="ref_flavor_default_flavor">default_flavor</h5>
</div>
<div class="sect4">
<h5 id="ref_flavor_little_endian_flavor">little_endian_flavor</h5>
</div>
<div class="sect4">
<h5 id="ref_flavor_big_endian_flavor">big_endian_flavor</h5>
</div>
</div>
<div class="sect3">
<h4 id="ref_get_integral_result">&lt;boost/hash2/get_integral_result.hpp&gt;</h4>
<div class="listingblock">
<div class="content">
<pre class="rouge highlight"><code data-lang="c++"><span class="k">namespace</span> <span class="n">boost</span> <span class="p">{</span>
<span class="k">namespace</span> <span class="n">hash2</span> <span class="p">{</span>
<span class="k">template</span><span class="o">&lt;</span><span class="k">class</span> <span class="nc">T</span><span class="p">,</span> <span class="k">class</span> <span class="nc">R</span><span class="p">&gt;</span> <span class="k">constexpr</span> <span class="n">T</span> <span class="n">get_integral_result</span><span class="p">(</span> <span class="n">R</span> <span class="k">const</span><span class="o">&amp;</span> <span class="n">r</span> <span class="p">)</span> <span class="k">noexcept</span><span class="p">;</span>
<span class="p">}</span> <span class="c1">// namespace hash2</span>
<span class="p">}</span> <span class="c1">// namespace boost</span></code></pre>
</div>
</div>
<div class="sect4">
<h5 id="ref_get_integral_result_get_integral_result">get_integral_result</h5>
<div class="listingblock">
<div class="content">
<pre class="rouge highlight"><code data-lang="c++"><span class="k">template</span><span class="o">&lt;</span><span class="k">class</span> <span class="nc">T</span><span class="p">,</span> <span class="k">class</span> <span class="nc">R</span><span class="p">&gt;</span> <span class="k">constexpr</span> <span class="n">T</span> <span class="n">get_integral_result</span><span class="p">(</span> <span class="n">R</span> <span class="k">const</span><span class="o">&amp;</span> <span class="n">r</span> <span class="p">)</span> <span class="k">noexcept</span><span class="p">;</span></code></pre>
</div>
</div>
<div class="dlist">
<dl>
<dt class="hdlist1">Requires: </dt>
<dd>
<p><code>T</code> must be an integral type that is not <code>bool</code>.
<code>R</code> must be a valid <em>hash algorithm</em> result type; that is, it must be an unsigned integer type, or an array-like type with a <code>value_type</code> of <code>unsigned char</code> (<code>std::array&lt;unsigned char, N&gt;</code> or <code>digest&lt;N&gt;</code>) and size of at least 8.</p>
</dd>
<dt class="hdlist1">Returns: </dt>
<dd>
<p>A value that is derived from <code>r</code> in a way that is approximately uniformly distributed over the possible values of <code>T</code>. <code>r</code> is assumed to have been produced by a <code>result()</code> invocation of a <em>hash algorithm</em>.</p>
</dd>
<dt class="hdlist1">Remarks: </dt>
<dd>
<p>When <code>R</code> is an array-like type, <code>get_integral_result</code> is allowed to assume that <code>r</code> has been produced by a high quality hash algorithm and that therefore its values are uniformly distributed over the entire domain of <code>R</code>.</p>
</dd>
<dt class="hdlist1">Example: </dt>
<dd>
<div class="listingblock">
<div class="content">
<pre class="rouge highlight"><code data-lang="c++"><span class="k">template</span><span class="o">&lt;</span><span class="k">class</span> <span class="nc">T</span><span class="p">,</span> <span class="k">class</span> <span class="nc">Hash</span><span class="p">&gt;</span> <span class="k">struct</span> <span class="nc">my_hash</span>
<span class="p">{</span>
<span class="n">std</span><span class="o">::</span><span class="kt">size_t</span> <span class="k">operator</span><span class="p">()(</span> <span class="n">std</span><span class="o">::</span><span class="n">string</span> <span class="k">const</span><span class="o">&amp;</span> <span class="n">st</span> <span class="p">)</span> <span class="k">const</span> <span class="k">noexcept</span>
<span class="p">{</span>
<span class="n">Hash</span> <span class="n">hash</span><span class="p">;</span>
<span class="n">boost</span><span class="o">::</span><span class="n">hash2</span><span class="o">::</span><span class="n">hash_append</span><span class="p">(</span> <span class="n">hash</span><span class="p">,</span> <span class="p">{},</span> <span class="n">st</span> <span class="p">);</span>
<span class="k">return</span> <span class="n">boost</span><span class="o">::</span><span class="n">hash2</span><span class="o">::</span><span class="n">get_integral_result</span><span class="o">&lt;</span><span class="n">std</span><span class="o">::</span><span class="kt">size_t</span><span class="o">&gt;</span><span class="p">(</span> <span class="n">hash</span><span class="p">.</span><span class="n">result</span><span class="p">()</span> <span class="p">);</span>
<span class="p">}</span>
<span class="p">};</span></code></pre>
</div>
</div>
</dd>
</dl>
</div>
</div>
</div>
<div class="sect3">
<h4 id="ref_is_trivially_equality_comparable">&lt;boost/hash2/is_trivially_equality_comparable.hpp&gt;</h4>
<div class="listingblock">
<div class="content">
<pre class="rouge highlight"><code data-lang="c++"><span class="k">namespace</span> <span class="n">boost</span> <span class="p">{</span>
<span class="k">namespace</span> <span class="n">hash2</span> <span class="p">{</span>
<span class="k">template</span><span class="o">&lt;</span><span class="k">class</span> <span class="nc">T</span><span class="p">&gt;</span> <span class="k">struct</span> <span class="nc">is_trivially_equality_comparable</span><span class="p">;</span>
<span class="p">}</span> <span class="c1">// namespace hash2</span>
<span class="p">}</span> <span class="c1">// namespace boost</span></code></pre>
</div>
</div>
<div class="sect4">
<h5 id="ref_is_trivially_equality_comparable_is_trivially_equality_comparable">is_trivially_equality_comparable</h5>
<div class="listingblock">
<div class="content">
<pre class="rouge highlight"><code data-lang="c++"><span class="k">template</span><span class="o">&lt;</span><span class="k">class</span> <span class="nc">T</span><span class="p">&gt;</span> <span class="k">struct</span> <span class="nc">is_trivially_equality_comparable</span><span class="o">:</span>
<span class="n">std</span><span class="o">::</span><span class="n">integral_constant</span><span class="o">&lt;</span> <span class="kt">bool</span><span class="p">,</span>
<span class="n">std</span><span class="o">::</span><span class="n">is_integral</span><span class="o">&lt;</span><span class="n">T</span><span class="o">&gt;::</span><span class="n">value</span> <span class="o">||</span> <span class="n">std</span><span class="o">::</span><span class="n">is_enum</span><span class="o">&lt;</span><span class="n">T</span><span class="o">&gt;::</span><span class="n">value</span> <span class="o">||</span> <span class="n">std</span><span class="o">::</span><span class="n">is_pointer</span><span class="o">&lt;</span><span class="n">T</span><span class="o">&gt;::</span><span class="n">value</span> <span class="o">&gt;</span>
<span class="p">{</span>
<span class="p">};</span>
<span class="k">template</span><span class="o">&lt;</span><span class="k">class</span> <span class="nc">T</span><span class="p">&gt;</span> <span class="k">struct</span> <span class="nc">is_trivially_equality_comparable</span><span class="o">&lt;</span><span class="n">T</span> <span class="k">const</span><span class="o">&gt;:</span>
<span class="n">is_trivially_equality_comparable</span><span class="o">&lt;</span><span class="n">T</span><span class="o">&gt;</span>
<span class="p">{</span>
<span class="p">};</span></code></pre>
</div>
</div>
<div class="paragraph">
<p>The trait <code>is_trivially_equality_comparable</code> is used by the library to detect types that are <em>trivially equality comparable</em>.</p>
</div>
<div class="paragraph">
<p>A type is <em>trivially equality comparable</em> if, for two values <code>x</code> and <code>y</code> of that type, <code>x == y</code> is equivalent to <code>std::memcmp( &amp;x, &amp;y, sizeof(x) ) == 0</code>.</p>
</div>
<div class="paragraph">
<p>That is, for trivially equality comparable types, comparing their values is the same as comparing their storage byte representations.</p>
</div>
<div class="paragraph">
<p>This allows <code>hash_append</code> to assume that the <em>message</em> identifying an object&#8217;s value is the same as the storage bytes of the object.</p>
</div>
<div class="paragraph">
<p><code>is_trivially_equality_comparable</code> can be specialized for user-defined types if the default implementation does not give the correct result.</p>
</div>
<div class="paragraph">
<p>For example, for the following type</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="rouge highlight"><code data-lang="c++"><span class="k">struct</span> <span class="nc">X</span>
<span class="p">{</span>
<span class="kt">int</span> <span class="n">v</span><span class="p">;</span>
<span class="p">};</span>
<span class="kt">bool</span> <span class="k">operator</span><span class="o">==</span><span class="p">(</span> <span class="n">X</span> <span class="k">const</span><span class="o">&amp;</span> <span class="n">x1</span><span class="p">,</span> <span class="n">X</span> <span class="k">const</span><span class="o">&amp;</span> <span class="n">x2</span> <span class="p">)</span>
<span class="p">{</span>
<span class="k">return</span> <span class="n">x1</span><span class="p">.</span><span class="n">v</span> <span class="o">==</span> <span class="n">x2</span><span class="p">.</span><span class="n">v</span><span class="p">;</span>
<span class="p">}</span></code></pre>
</div>
</div>
<div class="paragraph">
<p>(under the assumption that it has no padding bytes, that is, <code>sizeof(X) == sizeof(int)</code>)
<code>is_trivially_equality_comparable&lt;X&gt;::value</code> will be <code>false</code> by default, but the type meets the requirements for being trivially equality comparable, so a specialization can be added:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="rouge highlight"><code data-lang="c++"><span class="k">template</span><span class="o">&lt;</span><span class="p">&gt;</span> <span class="k">struct</span> <span class="nc">boost</span><span class="o">::</span><span class="n">hash2</span><span class="o">::</span><span class="n">is_trivially_equality_comparable</span><span class="o">&lt;</span><span class="n">X</span><span class="o">&gt;:</span> <span class="n">std</span><span class="o">::</span><span class="n">true_type</span> <span class="p">{};</span></code></pre>
</div>
</div>
<div class="paragraph">
<p>or, if you want to be on the safe side,</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="rouge highlight"><code data-lang="c++"><span class="k">template</span><span class="o">&lt;</span><span class="p">&gt;</span> <span class="k">struct</span> <span class="nc">boost</span><span class="o">::</span><span class="n">hash2</span><span class="o">::</span><span class="n">is_trivially_equality_comparable</span><span class="o">&lt;</span><span class="n">X</span><span class="o">&gt;:</span>
<span class="n">std</span><span class="o">::</span><span class="n">integral_constant</span><span class="o">&lt;</span><span class="kt">bool</span><span class="p">,</span> <span class="k">sizeof</span><span class="p">(</span><span class="n">X</span><span class="p">)</span> <span class="o">==</span> <span class="k">sizeof</span><span class="p">(</span><span class="kt">int</span><span class="p">)</span><span class="o">&gt;</span> <span class="p">{};</span></code></pre>
</div>
</div>
<div class="paragraph">
<p>On the other hand, the following type</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="rouge highlight"><code data-lang="c++"><span class="k">enum</span> <span class="n">E</span><span class="o">:</span> <span class="kt">unsigned</span> <span class="p">{};</span>
<span class="kt">bool</span> <span class="k">operator</span><span class="o">==</span><span class="p">(</span> <span class="n">E</span> <span class="n">e1</span><span class="p">,</span> <span class="n">E</span> <span class="n">e2</span> <span class="p">)</span>
<span class="p">{</span>
<span class="k">return</span> <span class="n">e1</span> <span class="o">%</span> <span class="mi">256</span> <span class="o">==</span> <span class="n">e2</span> <span class="o">%</span> <span class="mi">256</span><span class="p">;</span>
<span class="p">}</span></code></pre>
</div>
</div>
<div class="paragraph">
<p>is not trivially equality comparable (because <code>(E)0x204 == (E)0x704</code>, but <code>memcmp</code> will give a nonzero result), but <code>is_trivially_equality_comparable&lt;E&gt;::value</code> will be <code>true</code> by default.</p>
</div>
<div class="paragraph">
<p>In this (quite rare) case, a specialization can be added to report <code>false</code>:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="rouge highlight"><code data-lang="c++"><span class="k">template</span><span class="o">&lt;</span><span class="p">&gt;</span> <span class="k">struct</span> <span class="nc">boost</span><span class="o">::</span><span class="n">hash2</span><span class="o">::</span><span class="n">is_trivially_equality_comparable</span><span class="o">&lt;</span><span class="n">E</span><span class="o">&gt;:</span> <span class="n">std</span><span class="o">::</span><span class="n">false_type</span> <span class="p">{};</span></code></pre>
</div>
</div>
</div>
</div>
<div class="sect3">
<h4 id="ref_is_endian_independent">&lt;boost/hash2/is_endian_independent.hpp&gt;</h4>
<div class="listingblock">
<div class="content">
<pre class="rouge highlight"><code data-lang="c++"><span class="k">namespace</span> <span class="n">boost</span> <span class="p">{</span>
<span class="k">namespace</span> <span class="n">hash2</span> <span class="p">{</span>
<span class="k">template</span><span class="o">&lt;</span><span class="k">class</span> <span class="nc">T</span><span class="p">&gt;</span> <span class="k">struct</span> <span class="nc">is_endian_independent</span><span class="p">;</span>
<span class="p">}</span> <span class="c1">// namespace hash2</span>
<span class="p">}</span> <span class="c1">// namespace boost</span></code></pre>
</div>
</div>
<div class="sect4">
<h5 id="ref_is_endian_independent_is_endian_independent">is_endian_independent</h5>
<div class="listingblock">
<div class="content">
<pre class="rouge highlight"><code data-lang="c++"><span class="k">template</span><span class="o">&lt;</span><span class="k">class</span> <span class="nc">T</span><span class="p">&gt;</span> <span class="k">struct</span> <span class="nc">is_endian_independent</span><span class="o">:</span>
<span class="n">std</span><span class="o">::</span><span class="n">integral_constant</span><span class="o">&lt;</span> <span class="kt">bool</span><span class="p">,</span> <span class="k">sizeof</span><span class="p">(</span><span class="n">T</span><span class="p">)</span> <span class="o">==</span> <span class="mi">1</span> <span class="o">&gt;</span>
<span class="p">{</span>
<span class="p">};</span>
<span class="k">template</span><span class="o">&lt;</span><span class="k">class</span> <span class="nc">T</span><span class="p">&gt;</span> <span class="k">struct</span> <span class="nc">is_endian_independent</span><span class="o">&lt;</span><span class="n">T</span> <span class="k">const</span><span class="o">&gt;:</span>
<span class="n">is_endian_independent</span><span class="o">&lt;</span><span class="n">T</span><span class="o">&gt;</span>
<span class="p">{</span>
<span class="p">};</span></code></pre>
</div>
</div>
<div class="paragraph">
<p>The trait <code>is_endian_independent</code> is used by the library to detect <em>endian-independent</em> types.</p>
</div>
<div class="paragraph">
<p>A type is <em>endian-independent</em> if its memory representation is the same on little-endian and big-endian platforms.</p>
</div>
<div class="paragraph">
<p>This includes all single byte types (with a <code>sizeof</code> of 1) and all types whose constituent members are also endian-independent.</p>
</div>
<div class="paragraph">
<p>The default implementation of the trait only reports <code>true</code> for single byte types. It can be specialized for endian independent user-defined types.</p>
</div>
<div class="paragraph">
<p>For example, the following type</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="rouge highlight"><code data-lang="c++"><span class="k">struct</span> <span class="nc">X</span>
<span class="p">{</span>
<span class="kt">unsigned</span> <span class="kt">char</span> <span class="n">a</span><span class="p">;</span>
<span class="kt">unsigned</span> <span class="kt">char</span> <span class="n">b</span><span class="p">;</span>
<span class="kt">unsigned</span> <span class="kt">char</span> <span class="n">c</span><span class="p">;</span>
<span class="p">};</span></code></pre>
</div>
</div>
<div class="paragraph">
<p>is endian-independent, and <code>is_endian_independent</code> can be specialized appropriately for it:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="rouge highlight"><code data-lang="c++"><span class="k">template</span><span class="o">&lt;</span><span class="p">&gt;</span> <span class="k">struct</span> <span class="nc">boost</span><span class="o">::</span><span class="n">hash2</span><span class="o">::</span><span class="n">is_endian_independent</span><span class="o">&lt;</span><span class="n">X</span><span class="o">&gt;:</span> <span class="n">std</span><span class="o">::</span><span class="n">true_type</span> <span class="p">{};</span></code></pre>
</div>
</div>
</div>
</div>
<div class="sect3">
<h4 id="ref_is_contiguously_hashable">&lt;boost/hash2/is_contiguously_hashable.hpp&gt;</h4>
<div class="listingblock">
<div class="content">
<pre class="rouge highlight"><code data-lang="c++"><span class="cp">#include</span> <span class="cpf">&lt;boost/hash2/endian.hpp&gt;</span><span class="cp">
#include</span> <span class="cpf">&lt;boost/hash2/is_trivially_equality_comparable.hpp&gt;</span><span class="cp">
#include</span> <span class="cpf">&lt;boost/hash2/is_endian_independent.hpp&gt;</span><span class="cp">
</span>
<span class="k">namespace</span> <span class="n">boost</span> <span class="p">{</span>
<span class="k">namespace</span> <span class="n">hash2</span> <span class="p">{</span>
<span class="k">template</span><span class="o">&lt;</span><span class="k">class</span> <span class="nc">T</span><span class="p">,</span> <span class="n">endian</span> <span class="n">E</span><span class="p">&gt;</span> <span class="k">struct</span> <span class="nc">is_contiguously_hashable</span><span class="p">;</span>
<span class="p">}</span> <span class="c1">// namespace hash2</span>
<span class="p">}</span> <span class="c1">// namespace boost</span></code></pre>
</div>
</div>
<div class="sect4">
<h5 id="ref_is_contiguously_hashable_is_contiguously_hashable">is_contiguously_hashable</h5>
<div class="listingblock">
<div class="content">
<pre class="rouge highlight"><code data-lang="c++"><span class="k">template</span><span class="o">&lt;</span><span class="k">class</span> <span class="nc">T</span><span class="p">,</span> <span class="n">endian</span> <span class="n">E</span><span class="p">&gt;</span> <span class="k">struct</span> <span class="nc">is_contiguously_hashable</span><span class="o">:</span>
<span class="n">std</span><span class="o">::</span><span class="n">integral_constant</span><span class="o">&lt;</span><span class="kt">bool</span><span class="p">,</span>
<span class="n">is_trivially_equality_comparable</span><span class="o">&lt;</span><span class="n">T</span><span class="o">&gt;::</span><span class="n">value</span> <span class="o">&amp;&amp;</span>
<span class="p">(</span><span class="n">E</span> <span class="o">==</span> <span class="n">endian</span><span class="o">::</span><span class="n">native</span> <span class="o">||</span> <span class="n">is_endian_independent</span><span class="o">&lt;</span><span class="n">T</span><span class="o">&gt;::</span><span class="n">value</span><span class="p">)</span><span class="o">&gt;</span>
<span class="p">{</span>
<span class="p">};</span>
<span class="k">template</span><span class="o">&lt;</span><span class="k">class</span> <span class="nc">T</span><span class="p">,</span> <span class="n">std</span><span class="o">::</span><span class="kt">size_t</span> <span class="n">N</span><span class="p">,</span> <span class="n">endian</span> <span class="n">E</span><span class="p">&gt;</span> <span class="k">struct</span> <span class="nc">is_contiguously_hashable</span><span class="o">&lt;</span><span class="n">T</span><span class="p">[</span><span class="n">N</span><span class="p">],</span> <span class="n">E</span><span class="o">&gt;:</span>
<span class="n">is_contiguously_hashable</span><span class="o">&lt;</span><span class="n">T</span><span class="p">,</span> <span class="n">E</span><span class="o">&gt;</span>
<span class="p">{</span>
<span class="p">};</span></code></pre>
</div>
</div>
<div class="paragraph">
<p>The trait <code>is_contiguously_hashable</code> is used by the library to detect <em>contiguously hashable</em> types.</p>
</div>
<div class="paragraph">
<p>A type is <em>contiguously hashable</em> under a particular byte order <code>E</code> if the <em>message</em> that would have been produced for the type if it weren&#8217;t considered <em>contiguously hashable</em> is the same as its underlying storage byte representation.</p>
</div>
<div class="paragraph">
<p><code>hash_append(hash, flavor, value)</code>, when the type of <code>value</code> is <em>contiguously hashable</em> under the byte order requested by <code>flavor</code> (<code>decltype(flavor)::byte_order</code>), issues a single call to <code>hash.update(&amp;value, sizeof(value))</code> as an optimization.</p>
</div>
<div class="paragraph">
<p><code>is_contiguously_hashable</code> is not intended to be specialized for user-defined types. Its implementation relies on <code>is_trivially_equality_comparable</code> and <code>is_endian_independent</code>, and is correct as long as those underlying traits are correct.</p>
</div>
</div>
</div>
<div class="sect3">
<h4 id="ref_has_constant_size">&lt;boost/hash2/has_constant_size.hpp&gt;</h4>
<div class="listingblock">
<div class="content">
<pre class="rouge highlight"><code data-lang="c++"><span class="k">namespace</span> <span class="n">boost</span> <span class="p">{</span>
<span class="k">namespace</span> <span class="n">hash2</span> <span class="p">{</span>
<span class="k">template</span><span class="o">&lt;</span><span class="k">class</span> <span class="nc">T</span><span class="p">&gt;</span> <span class="k">struct</span> <span class="nc">has_constant_size</span><span class="p">;</span>
<span class="p">}</span> <span class="c1">// namespace hash2</span>
<span class="p">}</span> <span class="c1">// namespace boost</span></code></pre>
</div>
</div>
<div class="sect4">
<h5 id="ref_has_constant_size_has_constant_size">has_constant_size</h5>
<div class="listingblock">
<div class="content">
<pre class="rouge highlight"><code data-lang="c++"><span class="k">template</span><span class="o">&lt;</span><span class="k">class</span> <span class="nc">T</span><span class="p">&gt;</span> <span class="k">struct</span> <span class="nc">has_constant_size</span><span class="o">&lt;</span><span class="n">T</span><span class="o">&gt;:</span> <span class="n">std</span><span class="o">::</span><span class="n">integral_constant</span><span class="o">&lt;</span><span class="kt">bool</span><span class="p">,</span> <span class="cm">/*see below*/</span><span class="o">&gt;</span>
<span class="p">{</span>
<span class="p">};</span>
<span class="k">template</span><span class="o">&lt;</span><span class="k">class</span> <span class="nc">T</span><span class="p">&gt;</span> <span class="k">struct</span> <span class="nc">has_constant_size</span><span class="o">&lt;</span><span class="n">T</span> <span class="k">const</span><span class="o">&gt;:</span> <span class="n">has_constant_size</span><span class="o">&lt;</span><span class="n">T</span><span class="o">&gt;</span>
<span class="p">{</span>
<span class="p">};</span></code></pre>
</div>
</div>
<div class="paragraph">
<p>The trait <code>has_constant_size</code> is used by the library to detect container and range types that have a constant size.
This allows <code>hash_append</code> to not include the size in the <em>message</em>, as it doesn&#8217;t contribute to the object state.</p>
</div>
<div class="paragraph">
<p>A container or range type has constant size if for all values <code>v</code> of that type, <code>v.size()</code> has the same value.</p>
</div>
<div class="paragraph">
<p>The default implementation reports <code>true</code> for tuple-like types (those for which <code>std::tuple_size</code> is specialized), such as <code>std::array</code>, for <code>boost::array</code>, and for <code>digest</code>.</p>
</div>
<div class="paragraph">
<p><code>has_constant_size</code> can be specialized for user-defined container and range types that have constant size.</p>
</div>
<div class="paragraph">
<p>For example, <code>boost::uuids::uuid</code> has a constant size of 16, so a specialization can be added appropriately:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="rouge highlight"><code data-lang="c++"><span class="k">template</span><span class="o">&lt;</span><span class="p">&gt;</span> <span class="k">struct</span> <span class="nc">boost</span><span class="o">::</span><span class="n">hash2</span><span class="o">::</span><span class="n">has_constant_size</span><span class="o">&lt;</span><span class="n">boost</span><span class="o">::</span><span class="n">uuids</span><span class="o">::</span><span class="n">uuid</span><span class="o">&gt;:</span> <span class="n">std</span><span class="o">::</span><span class="n">true_type</span> <span class="p">{};</span></code></pre>
</div>
</div>
</div>
</div>
</div>
<div class="sect2">
<h3 id="ref_hashing_cpp_objects">Hashing C&#43;&#43; Objects</h3>
<div class="sect3">
<h4 id="ref_hash_append_fwd">&lt;boost/hash2/hash_append_fwd.hpp&gt;</h4>
<div class="sect4">
<h5 id="ref_hash_append_fwd_synopsis">Synopsis</h5>
<div class="listingblock">
<div class="content">
<pre class="rouge highlight"><code data-lang="c++"><span class="k">namespace</span> <span class="n">boost</span> <span class="p">{</span>
<span class="k">namespace</span> <span class="n">hash2</span> <span class="p">{</span>
<span class="k">template</span><span class="o">&lt;</span><span class="k">class</span> <span class="nc">Hash</span><span class="p">,</span> <span class="k">class</span> <span class="nc">Flavor</span><span class="p">,</span> <span class="k">class</span> <span class="nc">T</span><span class="p">&gt;</span>
<span class="k">constexpr</span> <span class="kt">void</span> <span class="n">hash_append</span><span class="p">(</span> <span class="n">Hash</span><span class="o">&amp;</span> <span class="n">h</span><span class="p">,</span> <span class="n">Flavor</span> <span class="k">const</span><span class="o">&amp;</span> <span class="n">f</span><span class="p">,</span> <span class="n">T</span> <span class="k">const</span><span class="o">&amp;</span> <span class="n">v</span> <span class="p">);</span>
<span class="k">template</span><span class="o">&lt;</span><span class="k">class</span> <span class="nc">Hash</span><span class="p">,</span> <span class="k">class</span> <span class="nc">Flavor</span><span class="p">,</span> <span class="k">class</span> <span class="nc">It</span><span class="p">&gt;</span>
<span class="k">constexpr</span> <span class="kt">void</span> <span class="n">hash_append_range</span><span class="p">(</span> <span class="n">Hash</span><span class="o">&amp;</span> <span class="n">h</span><span class="p">,</span> <span class="n">Flavor</span> <span class="k">const</span><span class="o">&amp;</span> <span class="n">f</span><span class="p">,</span> <span class="n">It</span> <span class="n">first</span><span class="p">,</span> <span class="n">It</span> <span class="n">last</span> <span class="p">);</span>
<span class="k">template</span><span class="o">&lt;</span><span class="k">class</span> <span class="nc">Hash</span><span class="p">,</span> <span class="k">class</span> <span class="nc">Flavor</span><span class="p">,</span> <span class="k">class</span> <span class="nc">T</span><span class="p">&gt;</span>
<span class="k">constexpr</span> <span class="kt">void</span> <span class="n">hash_append_size</span><span class="p">(</span> <span class="n">Hash</span><span class="o">&amp;</span> <span class="n">h</span><span class="p">,</span> <span class="n">Flavor</span> <span class="k">const</span><span class="o">&amp;</span> <span class="n">f</span><span class="p">,</span> <span class="n">T</span> <span class="k">const</span><span class="o">&amp;</span> <span class="n">v</span> <span class="p">);</span>
<span class="k">template</span><span class="o">&lt;</span><span class="k">class</span> <span class="nc">Hash</span><span class="p">,</span> <span class="k">class</span> <span class="nc">Flavor</span><span class="p">,</span> <span class="k">class</span> <span class="nc">It</span><span class="p">&gt;</span>
<span class="k">constexpr</span> <span class="kt">void</span> <span class="n">hash_append_sized_range</span><span class="p">(</span> <span class="n">Hash</span><span class="o">&amp;</span> <span class="n">h</span><span class="p">,</span> <span class="n">Flavor</span> <span class="k">const</span><span class="o">&amp;</span> <span class="n">f</span><span class="p">,</span> <span class="n">It</span> <span class="n">first</span><span class="p">,</span> <span class="n">It</span> <span class="n">last</span> <span class="p">);</span>
<span class="k">template</span><span class="o">&lt;</span><span class="k">class</span> <span class="nc">Hash</span><span class="p">,</span> <span class="k">class</span> <span class="nc">Flavor</span><span class="p">,</span> <span class="k">class</span> <span class="nc">It</span><span class="p">&gt;</span>
<span class="k">constexpr</span> <span class="kt">void</span> <span class="n">hash_append_unordered_range</span><span class="p">(</span> <span class="n">Hash</span><span class="o">&amp;</span> <span class="n">h</span><span class="p">,</span> <span class="n">Flavor</span> <span class="k">const</span><span class="o">&amp;</span> <span class="n">f</span><span class="p">,</span> <span class="n">It</span> <span class="n">first</span><span class="p">,</span> <span class="n">It</span> <span class="n">last</span> <span class="p">);</span>
<span class="k">struct</span> <span class="nc">hash_append_tag</span><span class="p">;</span>
<span class="p">}</span> <span class="c1">// namespace hash2</span>
<span class="p">}</span> <span class="c1">// namespace boost</span></code></pre>
</div>
</div>
</div>
</div>
<div class="sect3">
<h4 id="ref_hash_append">&lt;boost/hash2/hash_append.hpp&gt;</h4>
<div class="listingblock">
<div class="content">
<pre class="rouge highlight"><code data-lang="c++"><span class="cp">#include</span> <span class="cpf">&lt;boost/hash2/flavor.hpp&gt;</span><span class="cp">
</span>
<span class="k">namespace</span> <span class="n">boost</span> <span class="p">{</span>
<span class="k">namespace</span> <span class="n">hash2</span> <span class="p">{</span>
<span class="k">template</span><span class="o">&lt;</span><span class="k">class</span> <span class="nc">Hash</span><span class="p">,</span> <span class="k">class</span> <span class="nc">Flavor</span> <span class="o">=</span> <span class="n">default_flavor</span><span class="p">,</span> <span class="k">class</span> <span class="nc">T</span><span class="p">&gt;</span>
<span class="k">constexpr</span> <span class="kt">void</span> <span class="n">hash_append</span><span class="p">(</span> <span class="n">Hash</span><span class="o">&amp;</span> <span class="n">h</span><span class="p">,</span> <span class="n">Flavor</span> <span class="k">const</span><span class="o">&amp;</span> <span class="n">f</span><span class="p">,</span> <span class="n">T</span> <span class="k">const</span><span class="o">&amp;</span> <span class="n">v</span> <span class="p">);</span>
<span class="k">template</span><span class="o">&lt;</span><span class="k">class</span> <span class="nc">Hash</span><span class="p">,</span> <span class="k">class</span> <span class="nc">Flavor</span> <span class="o">=</span> <span class="n">default_flavor</span><span class="p">,</span> <span class="k">class</span> <span class="nc">It</span><span class="p">&gt;</span>
<span class="k">constexpr</span> <span class="kt">void</span> <span class="n">hash_append_range</span><span class="p">(</span> <span class="n">Hash</span><span class="o">&amp;</span> <span class="n">h</span><span class="p">,</span> <span class="n">Flavor</span> <span class="k">const</span><span class="o">&amp;</span> <span class="n">f</span><span class="p">,</span> <span class="n">It</span> <span class="n">first</span><span class="p">,</span> <span class="n">It</span> <span class="n">last</span> <span class="p">);</span>
<span class="k">template</span><span class="o">&lt;</span><span class="k">class</span> <span class="nc">Hash</span><span class="p">,</span> <span class="k">class</span> <span class="nc">Flavor</span> <span class="o">=</span> <span class="n">default_flavor</span><span class="p">,</span> <span class="k">class</span> <span class="nc">T</span><span class="p">&gt;</span>
<span class="k">constexpr</span> <span class="kt">void</span> <span class="n">hash_append_size</span><span class="p">(</span> <span class="n">Hash</span><span class="o">&amp;</span> <span class="n">h</span><span class="p">,</span> <span class="n">Flavor</span> <span class="k">const</span><span class="o">&amp;</span> <span class="n">f</span><span class="p">,</span> <span class="n">T</span> <span class="k">const</span><span class="o">&amp;</span> <span class="n">v</span> <span class="p">);</span>
<span class="k">template</span><span class="o">&lt;</span><span class="k">class</span> <span class="nc">Hash</span><span class="p">,</span> <span class="k">class</span> <span class="nc">Flavor</span> <span class="o">=</span> <span class="n">default_flavor</span><span class="p">,</span> <span class="k">class</span> <span class="nc">It</span><span class="p">&gt;</span>
<span class="k">constexpr</span> <span class="kt">void</span> <span class="n">hash_append_sized_range</span><span class="p">(</span> <span class="n">Hash</span><span class="o">&amp;</span> <span class="n">h</span><span class="p">,</span> <span class="n">Flavor</span> <span class="k">const</span><span class="o">&amp;</span> <span class="n">f</span><span class="p">,</span> <span class="n">It</span> <span class="n">first</span><span class="p">,</span> <span class="n">It</span> <span class="n">last</span> <span class="p">);</span>
<span class="k">template</span><span class="o">&lt;</span><span class="k">class</span> <span class="nc">Hash</span><span class="p">,</span> <span class="k">class</span> <span class="nc">Flavor</span> <span class="o">=</span> <span class="n">default_flavor</span><span class="p">,</span> <span class="k">class</span> <span class="nc">It</span><span class="p">&gt;</span>
<span class="k">constexpr</span> <span class="kt">void</span> <span class="n">hash_append_unordered_range</span><span class="p">(</span> <span class="n">Hash</span><span class="o">&amp;</span> <span class="n">h</span><span class="p">,</span> <span class="n">Flavor</span> <span class="k">const</span><span class="o">&amp;</span> <span class="n">f</span><span class="p">,</span> <span class="n">It</span> <span class="n">first</span><span class="p">,</span> <span class="n">It</span> <span class="n">last</span> <span class="p">);</span>
<span class="k">struct</span> <span class="nc">hash_append_tag</span><span class="p">;</span>
<span class="p">}</span> <span class="c1">// namespace hash2</span>
<span class="p">}</span> <span class="c1">// namespace boost</span></code></pre>
</div>
</div>
<div class="sect4">
<h5 id="ref_hash_append_hash_append">hash_append</h5>
</div>
<div class="sect4">
<h5 id="ref_hash_append_hash_append_range">hash_append_range</h5>
</div>
<div class="sect4">
<h5 id="ref_hash_append_hash_append_size">hash_append_size</h5>
</div>
<div class="sect4">
<h5 id="ref_hash_append_hash_append_sized_range">hash_append_sized_range</h5>
</div>
<div class="sect4">
<h5 id="ref_hash_append_hash_append_unordered_range">hash_append_unordered_range</h5>
</div>
<div class="sect4">
<h5 id="ref_hash_append_hash_append_tag">hash_append_tag</h5>
</div>
</div>
</div>
</div>
</div>
<div class="sect1">
<h2 id="copyright">Copyright and License</h2>
<div class="sectionbody">
<div class="paragraph">
<p>This documentation is copyright 2020, 2024 Peter Dimov and Christian Mazakas
and is distributed under the <a href="http://www.boost.org/LICENSE_1_0.txt">Boost Software License, Version 1.0</a>.</p>
</div>
</div>
</div>
</div>
<div id="footer">
<div id="footer-text">
Last updated 2024-11-13 12:47:41 +0200
</div>
</div>
<style>
*:not(pre)>code { background: none; color: #600000; }
:not(pre):not([class^=L])>code { background: none; color: #600000; }
</style>
</body>
</html>