<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0"><channel><title><![CDATA[C++ und sha1-Algorithmus]]></title><description><![CDATA[<p>hallo</p>
<p>ich will mit dem pseudocode aus <a href="http://de.wikipedia.org/wiki/Secure_Hash_Algorithm#SHA-1-Pseudocode" rel="nofollow">wikipedia</a> einen sha1-algorithmus programmieren. es geht mir in erster linie nicht um portability, es soll nur auf meinem system laufen (win64, little endian)<br />
das ist mein code:</p>
<pre><code class="language-cpp">template &lt;typename InputIterator&gt;
std::string generate_sha1(InputIterator begin, InputIterator end) {
	long long int seq_size = sizeof(InputIterator::value_type) * (end - begin); // initial size  of input sequence in bytes
	unsigned h[] = { 0x67452301, 0xEFCDAB89, 0x98BADCFE, 0x10325476, 0xC3D2E1F0 }; // initial 32-bit values for sha1 algorithm
	unsigned extension_size = 64 - (seq_size + 8) % 64; // size of 1000... extension in bytes
	std::vector&lt;unsigned char&gt; extend_seq(seq_size + extension_size + 8); // extended sequence = origin sequence + extension + message length
	std::copy(begin, end, extend_seq.begin()); // copy the original sequence
	extend_seq[seq_size] = 128; // add 1 bit at the end of the original sequence
	// fill up rest for 0
	for(long long int n = seq_size + 1; n != seq_size + extension_size; ++n)
		extend_seq[n] = 0;

	long long int be_seq_size = _byteswap_uint64(seq_size * 8); // swap endian of bitwise length of the original sequence
	std::memcpy(&amp;extend_seq[seq_size + extension_size], &amp;be_seq_size, 8); // concatenate big endian length at the end

	// for every 512bit block...
	for(unsigned n = 0; n &lt; extend_seq.size(); n += 64) {
		std::vector&lt;unsigned&gt; words(80); // 32-bit blocks of the extended sequence
		std::memcpy(&amp;words[0], &amp;extend_seq[n], 64); // copy 512 bit into new memory
		std::transform(words.begin(), words.end(), words.begin(), _byteswap_ulong); // transform words to big endian

		// now begin sha1-algorithm
		for(unsigned i = 16; i &lt; 80; ++i) {
			words[i] = left_rotate(words[i - 3] ^ words[i - 8] ^ words[i - 14] ^ words[i - 16], 1);
		}

		int a = h[0], b = h[1], c = h[2], d = h[3], e = h[4], f, k;
		for(unsigned n = 0; n &lt; 79; ++n) {
			if(n &gt;= 60) {
				f = b ^ c ^ d;
				k = 0xCA62C1D6;
			}
			else if(n &gt;= 40 &amp;&amp; n &lt;= 59) {
				f = (b &amp; c) | (b &amp; d)  | (c &amp; d);
				k = 0x8F1BBCDC;
			}
			else if(n &gt;= 20 &amp;&amp; n &lt;=39) {
				f = b ^ c ^ d;
				k = 0x6ED9EBA1;
			}
			else if(n &lt;= 19) {
				f = (b &amp; c) | (!b &amp; d);
				k = 0x5A827999;
			}

			unsigned tmp = left_rotate(a, 5) + f + e + k + words[n];
			e = d;
			d = c;
			c = left_rotate(b, 30);
			b = a;
			a = tmp;
		}

		h[0] += a;
		h[1] += b;
		h[2] += c;
		h[3] += d;
		h[4] += e;
	}

	// convert result into string, swap endian back to little endian
	std::stringstream ss;
	h[0] = _byteswap_ulong(h[0]);
	h[1] = _byteswap_ulong(h[1]);
	h[2] = _byteswap_ulong(h[2]);
	h[3] = _byteswap_ulong(h[3]);
	h[4] = _byteswap_ulong(h[4]);

	ss &lt;&lt; std::hex &lt;&lt; h[0] &lt;&lt; h[1] &lt;&lt; h[2] &lt;&lt; h[3] &lt;&lt; h[4];
	return ss.str();
}
</code></pre>
<p>leider kommt für den hash bei leerem string nicht das richtige ergebnis, weiß aber nicht, wo der fehler sein könnte.<br />
im wikipedia steht, dass man die 32-bit-wörter im big endian haben muss und dass das ergebnis in big endian ist, also konvertiere ich dort um. aber trotzdem klappt es nicht. was ist am endian-swap falsch?</p>
]]></description><link>https://www.c-plusplus.net/forum/topic/307718/c-und-sha1-algorithmus</link><generator>RSS for Node</generator><lastBuildDate>Thu, 06 Aug 2026 15:02:45 GMT</lastBuildDate><atom:link href="https://www.c-plusplus.net/forum/topic/307718.rss" rel="self" type="application/rss+xml"/><pubDate>Mon, 03 Sep 2012 15:33:25 GMT</pubDate><ttl>60</ttl><item><title><![CDATA[Reply to C++ und sha1-Algorithmus on Mon, 03 Sep 2012 15:33:25 GMT]]></title><description><![CDATA[<p>hallo</p>
<p>ich will mit dem pseudocode aus <a href="http://de.wikipedia.org/wiki/Secure_Hash_Algorithm#SHA-1-Pseudocode" rel="nofollow">wikipedia</a> einen sha1-algorithmus programmieren. es geht mir in erster linie nicht um portability, es soll nur auf meinem system laufen (win64, little endian)<br />
das ist mein code:</p>
<pre><code class="language-cpp">template &lt;typename InputIterator&gt;
std::string generate_sha1(InputIterator begin, InputIterator end) {
	long long int seq_size = sizeof(InputIterator::value_type) * (end - begin); // initial size  of input sequence in bytes
	unsigned h[] = { 0x67452301, 0xEFCDAB89, 0x98BADCFE, 0x10325476, 0xC3D2E1F0 }; // initial 32-bit values for sha1 algorithm
	unsigned extension_size = 64 - (seq_size + 8) % 64; // size of 1000... extension in bytes
	std::vector&lt;unsigned char&gt; extend_seq(seq_size + extension_size + 8); // extended sequence = origin sequence + extension + message length
	std::copy(begin, end, extend_seq.begin()); // copy the original sequence
	extend_seq[seq_size] = 128; // add 1 bit at the end of the original sequence
	// fill up rest for 0
	for(long long int n = seq_size + 1; n != seq_size + extension_size; ++n)
		extend_seq[n] = 0;

	long long int be_seq_size = _byteswap_uint64(seq_size * 8); // swap endian of bitwise length of the original sequence
	std::memcpy(&amp;extend_seq[seq_size + extension_size], &amp;be_seq_size, 8); // concatenate big endian length at the end

	// for every 512bit block...
	for(unsigned n = 0; n &lt; extend_seq.size(); n += 64) {
		std::vector&lt;unsigned&gt; words(80); // 32-bit blocks of the extended sequence
		std::memcpy(&amp;words[0], &amp;extend_seq[n], 64); // copy 512 bit into new memory
		std::transform(words.begin(), words.end(), words.begin(), _byteswap_ulong); // transform words to big endian

		// now begin sha1-algorithm
		for(unsigned i = 16; i &lt; 80; ++i) {
			words[i] = left_rotate(words[i - 3] ^ words[i - 8] ^ words[i - 14] ^ words[i - 16], 1);
		}

		int a = h[0], b = h[1], c = h[2], d = h[3], e = h[4], f, k;
		for(unsigned n = 0; n &lt; 79; ++n) {
			if(n &gt;= 60) {
				f = b ^ c ^ d;
				k = 0xCA62C1D6;
			}
			else if(n &gt;= 40 &amp;&amp; n &lt;= 59) {
				f = (b &amp; c) | (b &amp; d)  | (c &amp; d);
				k = 0x8F1BBCDC;
			}
			else if(n &gt;= 20 &amp;&amp; n &lt;=39) {
				f = b ^ c ^ d;
				k = 0x6ED9EBA1;
			}
			else if(n &lt;= 19) {
				f = (b &amp; c) | (!b &amp; d);
				k = 0x5A827999;
			}

			unsigned tmp = left_rotate(a, 5) + f + e + k + words[n];
			e = d;
			d = c;
			c = left_rotate(b, 30);
			b = a;
			a = tmp;
		}

		h[0] += a;
		h[1] += b;
		h[2] += c;
		h[3] += d;
		h[4] += e;
	}

	// convert result into string, swap endian back to little endian
	std::stringstream ss;
	h[0] = _byteswap_ulong(h[0]);
	h[1] = _byteswap_ulong(h[1]);
	h[2] = _byteswap_ulong(h[2]);
	h[3] = _byteswap_ulong(h[3]);
	h[4] = _byteswap_ulong(h[4]);

	ss &lt;&lt; std::hex &lt;&lt; h[0] &lt;&lt; h[1] &lt;&lt; h[2] &lt;&lt; h[3] &lt;&lt; h[4];
	return ss.str();
}
</code></pre>
<p>leider kommt für den hash bei leerem string nicht das richtige ergebnis, weiß aber nicht, wo der fehler sein könnte.<br />
im wikipedia steht, dass man die 32-bit-wörter im big endian haben muss und dass das ergebnis in big endian ist, also konvertiere ich dort um. aber trotzdem klappt es nicht. was ist am endian-swap falsch?</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2248154</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2248154</guid><dc:creator><![CDATA[sha1]]></dc:creator><pubDate>Mon, 03 Sep 2012 15:33:25 GMT</pubDate></item><item><title><![CDATA[Reply to C++ und sha1-Algorithmus on Mon, 03 Sep 2012 16:03:02 GMT]]></title><description><![CDATA[<pre><code class="language-cpp">for(unsigned n = 0; n &lt; 79; ++n)
</code></pre>
<p>sieht nicht richtig aus.<br />
Die gerechte Strafe für das loop-switch-Idiom.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2248159</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2248159</guid><dc:creator><![CDATA[camper]]></dc:creator><pubDate>Mon, 03 Sep 2012 16:03:02 GMT</pubDate></item><item><title><![CDATA[Reply to C++ und sha1-Algorithmus on Mon, 03 Sep 2012 16:07:28 GMT]]></title><description><![CDATA[<p>Darf man fragen warum du überhaupt noch etwas mit SHA1 machen willst, und nicht gleich einen Algorithmus der SHA2 Familie nimmst?</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2248162</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2248162</guid><dc:creator><![CDATA[cooky451]]></dc:creator><pubDate>Mon, 03 Sep 2012 16:07:28 GMT</pubDate></item><item><title><![CDATA[Reply to C++ und sha1-Algorithmus on Mon, 03 Sep 2012 17:11:37 GMT]]></title><description><![CDATA[<p>camper schrieb:</p>
<blockquote>
<pre><code class="language-cpp">for(unsigned n = 0; n &lt; 79; ++n)
</code></pre>
<p>sieht nicht richtig aus.<br />
Die gerechte Strafe für das loop-switch-Idiom.</p>
</blockquote>
<p>stimmt, das war falsch. aber es haut immernoch nicht hin. <img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/1f61e.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--disappointed_face"
      title=":("
      alt="😞"
    /><br />
mein left_rotate sieht so aus:</p>
<pre><code class="language-cpp">unsigned int left_rotate(unsigned int val, int n) {
	char t;
	while(n--) {
		if(val &amp; 0x80000000)  t = 1;
		else t = 0;
		val &lt;&lt;= 1;
		val |= t;
	}
	return val;
}
</code></pre>
]]></description><link>https://www.c-plusplus.net/forum/post/2248185</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2248185</guid><dc:creator><![CDATA[sha1]]></dc:creator><pubDate>Mon, 03 Sep 2012 17:11:37 GMT</pubDate></item><item><title><![CDATA[Reply to C++ und sha1-Algorithmus on Mon, 03 Sep 2012 17:48:02 GMT]]></title><description><![CDATA[<p>Dein Shift sollte zwar passen aber was spricht gegen folgende Lösung:</p>
<pre><code class="language-cpp">unsigned int loopless_left_rotate( unsigned int val, int n )
{
	return ( val &lt;&lt; n ) | ( val &gt;&gt; ( sizeof( unsigned int ) * CHAR_BIT - n ) );
}
</code></pre>
]]></description><link>https://www.c-plusplus.net/forum/post/2248190</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2248190</guid><dc:creator><![CDATA[rean]]></dc:creator><pubDate>Mon, 03 Sep 2012 17:48:02 GMT</pubDate></item></channel></rss>