<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
	<id>https://the.satanic.wiki/index.php?action=history&amp;feed=atom&amp;title=Module%3AHash</id>
	<title>Module:Hash - Revision history</title>
	<link rel="self" type="application/atom+xml" href="https://the.satanic.wiki/index.php?action=history&amp;feed=atom&amp;title=Module%3AHash"/>
	<link rel="alternate" type="text/html" href="https://the.satanic.wiki/index.php?title=Module:Hash&amp;action=history"/>
	<updated>2026-04-20T01:25:14Z</updated>
	<subtitle>Revision history for this page on the wiki</subtitle>
	<generator>MediaWiki 1.43.0</generator>
	<entry>
		<id>https://the.satanic.wiki/index.php?title=Module:Hash&amp;diff=11079&amp;oldid=prev</id>
		<title>WikiGOD at 06:03, 2 May 2021</title>
		<link rel="alternate" type="text/html" href="https://the.satanic.wiki/index.php?title=Module:Hash&amp;diff=11079&amp;oldid=prev"/>
		<updated>2021-05-02T06:03:48Z</updated>

		<summary type="html">&lt;p&gt;&lt;/p&gt;
&lt;table style=&quot;background-color: #fff; color: #202122;&quot; data-mw=&quot;interface&quot;&gt;
				&lt;col class=&quot;diff-marker&quot; /&gt;
				&lt;col class=&quot;diff-content&quot; /&gt;
				&lt;col class=&quot;diff-marker&quot; /&gt;
				&lt;col class=&quot;diff-content&quot; /&gt;
				&lt;tr class=&quot;diff-title&quot; lang=&quot;en&quot;&gt;
				&lt;td colspan=&quot;2&quot; style=&quot;background-color: #fff; color: #202122; text-align: center;&quot;&gt;← Older revision&lt;/td&gt;
				&lt;td colspan=&quot;2&quot; style=&quot;background-color: #fff; color: #202122; text-align: center;&quot;&gt;Revision as of 06:03, 2 May 2021&lt;/td&gt;
				&lt;/tr&gt;&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot; id=&quot;mw-diff-left-l1&quot;&gt;Line 1:&lt;/td&gt;
&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot;&gt;Line 1:&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;-- Imports&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;-- Imports&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;br&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;br&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;−&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #ffe49c; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;local luts = mw.loadData(&#039;&lt;del style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;Dev&lt;/del&gt;:Hash/LUTs&#039;)&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;local luts = mw.loadData(&#039;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;Module&lt;/ins&gt;:Hash/LUTs&#039;)&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;br&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;br&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;-- Utils: bit manipulation&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;-- Utils: bit manipulation&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;

&lt;!-- diff cache key zzegtzyr_mw19226-mwjf_:diff:1.41:old-10912:rev-11079:php=table --&gt;
&lt;/table&gt;</summary>
		<author><name>WikiGOD</name></author>
	</entry>
	<entry>
		<id>https://the.satanic.wiki/index.php?title=Module:Hash&amp;diff=10912&amp;oldid=prev</id>
		<title>WikiGOD: 1 revision imported</title>
		<link rel="alternate" type="text/html" href="https://the.satanic.wiki/index.php?title=Module:Hash&amp;diff=10912&amp;oldid=prev"/>
		<updated>2021-04-30T02:23:56Z</updated>

		<summary type="html">&lt;p&gt;1 revision imported&lt;/p&gt;
&lt;table style=&quot;background-color: #fff; color: #202122;&quot; data-mw=&quot;interface&quot;&gt;
				&lt;col class=&quot;diff-marker&quot; /&gt;
				&lt;col class=&quot;diff-content&quot; /&gt;
				&lt;col class=&quot;diff-marker&quot; /&gt;
				&lt;col class=&quot;diff-content&quot; /&gt;
				&lt;tr class=&quot;diff-title&quot; lang=&quot;en&quot;&gt;
				&lt;td colspan=&quot;2&quot; style=&quot;background-color: #fff; color: #202122; text-align: center;&quot;&gt;← Older revision&lt;/td&gt;
				&lt;td colspan=&quot;2&quot; style=&quot;background-color: #fff; color: #202122; text-align: center;&quot;&gt;Revision as of 02:23, 30 April 2021&lt;/td&gt;
				&lt;/tr&gt;&lt;tr&gt;&lt;td colspan=&quot;4&quot; class=&quot;diff-notice&quot; lang=&quot;en&quot;&gt;&lt;div class=&quot;mw-diff-empty&quot;&gt;(No difference)&lt;/div&gt;
&lt;/td&gt;&lt;/tr&gt;
&lt;!-- diff cache key zzegtzyr_mw19226-mwjf_:diff:1.41:old-10911:rev-10912 --&gt;
&lt;/table&gt;</summary>
		<author><name>WikiGOD</name></author>
	</entry>
	<entry>
		<id>https://the.satanic.wiki/index.php?title=Module:Hash&amp;diff=10911&amp;oldid=prev</id>
		<title>Mediawiki&gt;Puxlit: 😂😂😂🤦🏻‍♂️🤦🏻‍♂️🤦🏻‍♂️</title>
		<link rel="alternate" type="text/html" href="https://the.satanic.wiki/index.php?title=Module:Hash&amp;diff=10911&amp;oldid=prev"/>
		<updated>2020-08-20T11:55:37Z</updated>

		<summary type="html">&lt;p&gt;😂😂😂🤦🏻‍♂️🤦🏻‍♂️🤦🏻‍♂️&lt;/p&gt;
&lt;p&gt;&lt;b&gt;New page&lt;/b&gt;&lt;/p&gt;&lt;div&gt;-- Imports&lt;br /&gt;
&lt;br /&gt;
local luts = mw.loadData(&amp;#039;Dev:Hash/LUTs&amp;#039;)&lt;br /&gt;
&lt;br /&gt;
-- Utils: bit manipulation&lt;br /&gt;
&lt;br /&gt;
local function u32_add(a, b)&lt;br /&gt;
    return (a + b) % 0x100000000&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local function u32_and(a, b)&lt;br /&gt;
    local xx, z = 1, 0&lt;br /&gt;
    while (a &amp;gt; 0) and (b &amp;gt; 0) do&lt;br /&gt;
        if ((a % 2) + (b % 2)) == 2 then z = z + xx end&lt;br /&gt;
        a, b, xx = math.floor(a / 2), math.floor(b / 2), xx * 2&lt;br /&gt;
    end&lt;br /&gt;
    return z&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local function u32_not(a)&lt;br /&gt;
    return 0xffffffff - a&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local function u32_or(a, b)&lt;br /&gt;
    local xx, z = 1, 0&lt;br /&gt;
    while (a &amp;gt; 0) or (b &amp;gt; 0) do&lt;br /&gt;
        if ((a % 2) + (b % 2)) &amp;gt; 0 then z = z + xx end&lt;br /&gt;
        a, b, xx = math.floor(a / 2), math.floor(b / 2), xx * 2&lt;br /&gt;
    end&lt;br /&gt;
    return z&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local function u32_rotl(a, x)&lt;br /&gt;
    -- We could do a `x = x % 32` or `assert(x % 32 == 0)`, but nah...&lt;br /&gt;
    local xx = math.floor(2 ^ (32 - x))&lt;br /&gt;
    return math.floor(a / xx) + ((a % xx) * math.floor(2 ^ x))&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local function u32_xor(a, b)&lt;br /&gt;
    local xx, z = 1, 0&lt;br /&gt;
    while (a ~= b) do&lt;br /&gt;
        if (a % 2) ~= (b % 2) then z = z + xx end&lt;br /&gt;
        a, b, xx = math.floor(a / 2), math.floor(b / 2), xx * 2&lt;br /&gt;
    end&lt;br /&gt;
    return z&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-- Utils: structs&lt;br /&gt;
&lt;br /&gt;
local function pack_le_u32(u32)&lt;br /&gt;
    local b0 = u32 % 0x100; u32 = math.floor(u32 / 0x100)&lt;br /&gt;
    local b1 = u32 % 0x100; u32 = math.floor(u32 / 0x100)&lt;br /&gt;
    local b2 = u32 % 0x100; u32 = math.floor(u32 / 0x100)&lt;br /&gt;
    local b3 = u32 % 0x100&lt;br /&gt;
    return string.char(b0, b1, b2, b3)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local function pack_le_u64(u64)&lt;br /&gt;
    local b0 = u64 % 0x100; u64 = math.floor(u64 / 0x100)&lt;br /&gt;
    local b1 = u64 % 0x100; u64 = math.floor(u64 / 0x100)&lt;br /&gt;
    local b2 = u64 % 0x100; u64 = math.floor(u64 / 0x100)&lt;br /&gt;
    local b3 = u64 % 0x100; u64 = math.floor(u64 / 0x100)&lt;br /&gt;
    local b4 = u64 % 0x100; u64 = math.floor(u64 / 0x100)&lt;br /&gt;
    local b5 = u64 % 0x100; u64 = math.floor(u64 / 0x100)&lt;br /&gt;
    local b6 = u64 % 0x100; u64 = math.floor(u64 / 0x100)&lt;br /&gt;
    local b7 = u64 % 0x100&lt;br /&gt;
    return string.char(b0, b1, b2, b3, b4, b5, b6, b7)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local function unpack_le_u32(bytes, offset)&lt;br /&gt;
    return (string.byte(bytes, offset    )            ) +&lt;br /&gt;
           (string.byte(bytes, offset + 1) *     0x100) +&lt;br /&gt;
           (string.byte(bytes, offset + 2) *   0x10000) +&lt;br /&gt;
           (string.byte(bytes, offset + 3) * 0x1000000)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-- Utils: representation&lt;br /&gt;
&lt;br /&gt;
local function bytes_to_hex(bytes)&lt;br /&gt;
    local repr = &amp;#039;&amp;#039;&lt;br /&gt;
    for i = 1, #bytes do&lt;br /&gt;
        repr = repr .. string.format(&amp;#039;%02x&amp;#039;, string.byte(bytes, i))&lt;br /&gt;
    end&lt;br /&gt;
    return repr&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-- Utils: MW helpers&lt;br /&gt;
&lt;br /&gt;
local function make_message(frame)&lt;br /&gt;
    local i, message = 0, &amp;#039;&amp;#039;&lt;br /&gt;
    for k, v in ipairs(frame.args) do&lt;br /&gt;
        if i &amp;gt; 0 then message = message .. &amp;#039;\0&amp;#039; end&lt;br /&gt;
        i = i + 1&lt;br /&gt;
        message = message .. v&lt;br /&gt;
    end&lt;br /&gt;
    -- Per Scribunto docs, we can&amp;#039;t count the number of anonymous/numbered params with `#frame.args`&lt;br /&gt;
    assert(i &amp;gt; 0, &amp;#039;Function must be invoked with at least one anonymous or numbered parameter&amp;#039;)&lt;br /&gt;
    return message&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-- Utils: hash functions&lt;br /&gt;
&lt;br /&gt;
local function md5_f(x, y, z)&lt;br /&gt;
    return u32_or(u32_and(x, y), u32_and(u32_not(x), z))&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local function md5_g(x, y, z)&lt;br /&gt;
    return u32_or(u32_and(x, z), u32_and(y, u32_not(z)))&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local function md5_h(x, y, z)&lt;br /&gt;
    return u32_xor(u32_xor(x, y), z)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local function md5_i(x, y, z)&lt;br /&gt;
    return u32_xor(y, u32_or(x, u32_not(z)))&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local function md5_op(a, b, c, d, aux, x_k, s, t_i)&lt;br /&gt;
    return u32_add(b, u32_rotl(u32_add(u32_add(a, aux(b, c, d)), u32_add(x_k, t_i)), s))&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local function md5_init()&lt;br /&gt;
    return {&lt;br /&gt;
        is_finalized = false,&lt;br /&gt;
        buffer = &amp;#039;&amp;#039;,&lt;br /&gt;
        message_length = 0,&lt;br /&gt;
        -- Initialize MD buffer (per section 3.3 of RFC 1321)&lt;br /&gt;
        a = 0x67452301,&lt;br /&gt;
        b = 0xefcdab89,&lt;br /&gt;
        c = 0x98badcfe,&lt;br /&gt;
        d = 0x10325476&lt;br /&gt;
    }&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local function md5_update(context, message)&lt;br /&gt;
    assert(not context.is_finalized, &amp;#039;MD5 context has already been finalized&amp;#039;)&lt;br /&gt;
&lt;br /&gt;
    local buffer = context.buffer .. message&lt;br /&gt;
    local partial_block_length = #buffer % 64&lt;br /&gt;
    context.buffer = (partial_block_length &amp;gt; 0) and string.sub(buffer, -partial_block_length) or &amp;#039;&amp;#039;&lt;br /&gt;
    context.message_length = context.message_length + #message&lt;br /&gt;
&lt;br /&gt;
    -- Process each block (per section 3.4 of RFC 1321)&lt;br /&gt;
    for i = 0, math.floor(#buffer / 64) - 1 do&lt;br /&gt;
        local x = {}; for j = 0, 15 do x[j + 1] = unpack_le_u32(buffer, (i * 64) + (j * 4) + 1) end&lt;br /&gt;
&lt;br /&gt;
        local a, b, c, d = context.a, context.b, context.c, context.d&lt;br /&gt;
&lt;br /&gt;
        -- Round one&lt;br /&gt;
        a = md5_op(a, b, c, d, md5_f, x[ 1],  7, luts.md5_t[ 1])&lt;br /&gt;
        d = md5_op(d, a, b, c, md5_f, x[ 2], 12, luts.md5_t[ 2])&lt;br /&gt;
        c = md5_op(c, d, a, b, md5_f, x[ 3], 17, luts.md5_t[ 3])&lt;br /&gt;
        b = md5_op(b, c, d, a, md5_f, x[ 4], 22, luts.md5_t[ 4])&lt;br /&gt;
        a = md5_op(a, b, c, d, md5_f, x[ 5],  7, luts.md5_t[ 5])&lt;br /&gt;
        d = md5_op(d, a, b, c, md5_f, x[ 6], 12, luts.md5_t[ 6])&lt;br /&gt;
        c = md5_op(c, d, a, b, md5_f, x[ 7], 17, luts.md5_t[ 7])&lt;br /&gt;
        b = md5_op(b, c, d, a, md5_f, x[ 8], 22, luts.md5_t[ 8])&lt;br /&gt;
        a = md5_op(a, b, c, d, md5_f, x[ 9],  7, luts.md5_t[ 9])&lt;br /&gt;
        d = md5_op(d, a, b, c, md5_f, x[10], 12, luts.md5_t[10])&lt;br /&gt;
        c = md5_op(c, d, a, b, md5_f, x[11], 17, luts.md5_t[11])&lt;br /&gt;
        b = md5_op(b, c, d, a, md5_f, x[12], 22, luts.md5_t[12])&lt;br /&gt;
        a = md5_op(a, b, c, d, md5_f, x[13],  7, luts.md5_t[13])&lt;br /&gt;
        d = md5_op(d, a, b, c, md5_f, x[14], 12, luts.md5_t[14])&lt;br /&gt;
        c = md5_op(c, d, a, b, md5_f, x[15], 17, luts.md5_t[15])&lt;br /&gt;
        b = md5_op(b, c, d, a, md5_f, x[16], 22, luts.md5_t[16])&lt;br /&gt;
&lt;br /&gt;
        -- Round two&lt;br /&gt;
        a = md5_op(a, b, c, d, md5_g, x[ 2],  5, luts.md5_t[17])&lt;br /&gt;
        d = md5_op(d, a, b, c, md5_g, x[ 7],  9, luts.md5_t[18])&lt;br /&gt;
        c = md5_op(c, d, a, b, md5_g, x[12], 14, luts.md5_t[19])&lt;br /&gt;
        b = md5_op(b, c, d, a, md5_g, x[ 1], 20, luts.md5_t[20])&lt;br /&gt;
        a = md5_op(a, b, c, d, md5_g, x[ 6],  5, luts.md5_t[21])&lt;br /&gt;
        d = md5_op(d, a, b, c, md5_g, x[11],  9, luts.md5_t[22])&lt;br /&gt;
        c = md5_op(c, d, a, b, md5_g, x[16], 14, luts.md5_t[23])&lt;br /&gt;
        b = md5_op(b, c, d, a, md5_g, x[ 5], 20, luts.md5_t[24])&lt;br /&gt;
        a = md5_op(a, b, c, d, md5_g, x[10],  5, luts.md5_t[25])&lt;br /&gt;
        d = md5_op(d, a, b, c, md5_g, x[15],  9, luts.md5_t[26])&lt;br /&gt;
        c = md5_op(c, d, a, b, md5_g, x[ 4], 14, luts.md5_t[27])&lt;br /&gt;
        b = md5_op(b, c, d, a, md5_g, x[ 9], 20, luts.md5_t[28])&lt;br /&gt;
        a = md5_op(a, b, c, d, md5_g, x[14],  5, luts.md5_t[29])&lt;br /&gt;
        d = md5_op(d, a, b, c, md5_g, x[ 3],  9, luts.md5_t[30])&lt;br /&gt;
        c = md5_op(c, d, a, b, md5_g, x[ 8], 14, luts.md5_t[31])&lt;br /&gt;
        b = md5_op(b, c, d, a, md5_g, x[13], 20, luts.md5_t[32])&lt;br /&gt;
&lt;br /&gt;
        -- Round three&lt;br /&gt;
        a = md5_op(a, b, c, d, md5_h, x[ 6],  4, luts.md5_t[33])&lt;br /&gt;
        d = md5_op(d, a, b, c, md5_h, x[ 9], 11, luts.md5_t[34])&lt;br /&gt;
        c = md5_op(c, d, a, b, md5_h, x[12], 16, luts.md5_t[35])&lt;br /&gt;
        b = md5_op(b, c, d, a, md5_h, x[15], 23, luts.md5_t[36])&lt;br /&gt;
        a = md5_op(a, b, c, d, md5_h, x[ 2],  4, luts.md5_t[37])&lt;br /&gt;
        d = md5_op(d, a, b, c, md5_h, x[ 5], 11, luts.md5_t[38])&lt;br /&gt;
        c = md5_op(c, d, a, b, md5_h, x[ 8], 16, luts.md5_t[39])&lt;br /&gt;
        b = md5_op(b, c, d, a, md5_h, x[11], 23, luts.md5_t[40])&lt;br /&gt;
        a = md5_op(a, b, c, d, md5_h, x[14],  4, luts.md5_t[41])&lt;br /&gt;
        d = md5_op(d, a, b, c, md5_h, x[ 1], 11, luts.md5_t[42])&lt;br /&gt;
        c = md5_op(c, d, a, b, md5_h, x[ 4], 16, luts.md5_t[43])&lt;br /&gt;
        b = md5_op(b, c, d, a, md5_h, x[ 7], 23, luts.md5_t[44])&lt;br /&gt;
        a = md5_op(a, b, c, d, md5_h, x[10],  4, luts.md5_t[45])&lt;br /&gt;
        d = md5_op(d, a, b, c, md5_h, x[13], 11, luts.md5_t[46])&lt;br /&gt;
        c = md5_op(c, d, a, b, md5_h, x[16], 16, luts.md5_t[47])&lt;br /&gt;
        b = md5_op(b, c, d, a, md5_h, x[ 3], 23, luts.md5_t[48])&lt;br /&gt;
&lt;br /&gt;
        -- Round four&lt;br /&gt;
        a = md5_op(a, b, c, d, md5_i, x[ 1],  6, luts.md5_t[49])&lt;br /&gt;
        d = md5_op(d, a, b, c, md5_i, x[ 8], 10, luts.md5_t[50])&lt;br /&gt;
        c = md5_op(c, d, a, b, md5_i, x[15], 15, luts.md5_t[51])&lt;br /&gt;
        b = md5_op(b, c, d, a, md5_i, x[ 6], 21, luts.md5_t[52])&lt;br /&gt;
        a = md5_op(a, b, c, d, md5_i, x[13],  6, luts.md5_t[53])&lt;br /&gt;
        d = md5_op(d, a, b, c, md5_i, x[ 4], 10, luts.md5_t[54])&lt;br /&gt;
        c = md5_op(c, d, a, b, md5_i, x[11], 15, luts.md5_t[55])&lt;br /&gt;
        b = md5_op(b, c, d, a, md5_i, x[ 2], 21, luts.md5_t[56])&lt;br /&gt;
        a = md5_op(a, b, c, d, md5_i, x[ 9],  6, luts.md5_t[57])&lt;br /&gt;
        d = md5_op(d, a, b, c, md5_i, x[16], 10, luts.md5_t[58])&lt;br /&gt;
        c = md5_op(c, d, a, b, md5_i, x[ 7], 15, luts.md5_t[59])&lt;br /&gt;
        b = md5_op(b, c, d, a, md5_i, x[14], 21, luts.md5_t[60])&lt;br /&gt;
        a = md5_op(a, b, c, d, md5_i, x[ 5],  6, luts.md5_t[61])&lt;br /&gt;
        d = md5_op(d, a, b, c, md5_i, x[12], 10, luts.md5_t[62])&lt;br /&gt;
        c = md5_op(c, d, a, b, md5_i, x[ 3], 15, luts.md5_t[63])&lt;br /&gt;
        b = md5_op(b, c, d, a, md5_i, x[10], 21, luts.md5_t[64])&lt;br /&gt;
&lt;br /&gt;
        context.a = u32_add(context.a, a)&lt;br /&gt;
        context.b = u32_add(context.b, b)&lt;br /&gt;
        context.c = u32_add(context.c, c)&lt;br /&gt;
        context.d = u32_add(context.d, d)&lt;br /&gt;
    end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local function md5_finalize(context)&lt;br /&gt;
    assert(not context.is_finalized, &amp;#039;MD5 context has already been finalized&amp;#039;)&lt;br /&gt;
&lt;br /&gt;
    -- Pad (per sections 3.1 and 3.2 of RFC 1321)&lt;br /&gt;
    local padding = &amp;#039;\128&amp;#039; .. string.rep(&amp;#039;\0&amp;#039;, ((56 - ((context.message_length + 1) % 64)) + 64) % 64) .. pack_le_u64(context.message_length * 8)&lt;br /&gt;
    assert(#context.buffer + #padding == ((#context.buffer &amp;lt; 56) and 64 or 128))&lt;br /&gt;
&lt;br /&gt;
    md5_update(context, padding)&lt;br /&gt;
&lt;br /&gt;
    -- Concatenate (per section 3.5 of RFC 1321)&lt;br /&gt;
    local digest = pack_le_u32(context.a) .. pack_le_u32(context.b) .. pack_le_u32(context.c) .. pack_le_u32(context.d)&lt;br /&gt;
&lt;br /&gt;
    -- Clean up&lt;br /&gt;
    context.is_finalized = true&lt;br /&gt;
    context.buffer = nil&lt;br /&gt;
&lt;br /&gt;
    return digest&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local function MD5(message)&lt;br /&gt;
    local context = md5_init()&lt;br /&gt;
    if message then md5_update(context, message) end&lt;br /&gt;
&lt;br /&gt;
    local iface, memoized_digest, memoized_hexdigest = {}, nil, nil&lt;br /&gt;
&lt;br /&gt;
    function iface.update(message)&lt;br /&gt;
        assert(memoized_digest == nil, &amp;#039;MD5 context has already been finalized&amp;#039;)&lt;br /&gt;
        md5_update(context, message)&lt;br /&gt;
        return iface  -- Facilitate fluent interface&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    function iface.digest()&lt;br /&gt;
        if memoized_digest == nil then memoized_digest = md5_finalize(context); context = nil end&lt;br /&gt;
        return memoized_digest&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    function iface.hexdigest()&lt;br /&gt;
        if memoized_hexdigest == nil then memoized_hexdigest = bytes_to_hex(iface.digest()) end&lt;br /&gt;
        return memoized_hexdigest&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    return iface&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-- Exports&lt;br /&gt;
&lt;br /&gt;
local p = {}&lt;br /&gt;
&lt;br /&gt;
-- Exports: for use in other libraries&lt;br /&gt;
&lt;br /&gt;
p.MD5 = MD5&lt;br /&gt;
&lt;br /&gt;
-- Exports: invocables&lt;br /&gt;
&lt;br /&gt;
function p.md5_hexdigest(frame)&lt;br /&gt;
    local message = make_message(frame)&lt;br /&gt;
    return mw.hash and mw.hash.hashValue(&amp;#039;md5&amp;#039;, message) or MD5(message).hexdigest()&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
return p&lt;/div&gt;</summary>
		<author><name>Mediawiki&gt;Puxlit</name></author>
	</entry>
</feed>