SHA-1: Difference between revisions

5,524 bytes added ,  3 months ago
m
m (syntax highlighting fixup automation)
m (→‎{{header|Wren}}: Minor tidy)
 
(6 intermediate revisions by 3 users not shown)
Line 1,161:
{{out}}
<pre>Rosetta Code as a sha1 digest :48c98f7e5a6e736d790ab740dfc3f51a61abe2b5 !</pre>
 
===Without external libraries===
<syntaxhighlight lang="c++">
#include <bit>
#include <cstdint>
#include <iomanip>
#include <iostream>
#include <sstream>
#include <string>
#include <vector>
 
class SHA1 {
public:
std::string message_digest(const std::string& message) {
std::vector<uint32_t> state = { 0x67452301, 0xefcdab89, 0x98badcfe, 0x10325476, 0xc3d2e1f0 };
 
const std::vector<int8_t> bytes = add_padding(message);
for ( uint64_t i = 0; i < bytes.size() / BLOCK_LENGTH; ++i ) {
std::vector<uint32_t> values(80, 0);
for ( uint32_t j = 0; j < BLOCK_LENGTH; ++j ) {
values[j / 4] |= ( bytes[i * BLOCK_LENGTH + j] & 0xff ) << ( ( 3 - j % 4 ) * 8 );
}
for ( uint32_t j = 16; j < 80; ++j ) {
uint32_t value = values[j - 3] ^ values[j - 8] ^ values[j - 14] ^ values[j - 16];
values[j] = std::rotl(value, 1);
}
 
uint32_t a = state[0], b = state[1], c = state[2], d = state[3], e = state[4];
uint32_t f = 0, k = 0;
for ( uint32_t j = 0; j < 80; ++j ) {
switch ( j / 20 ) {
case 0 : { f = ( b & c ) | ( ~b & d ); k = 0x5a827999; break; }
case 1 : { f = b ^ c ^ d; k = 0x6ed9eba1; break; }
case 2 : { f = ( b & c ) | ( b & d ) | ( c & d ); k = 0x8f1bbcdc; break; }
case 3 : { f = b ^ c ^ d; k = 0xca62c1d6; break; }
}
 
uint32_t temp = std::rotl(a, 5) + f + e + k + values[j];
e = d; d = c; c = std::rotl(b, 30); b = a; a = temp;
}
 
state[0] += a; state[1] += b; state[2] += c; state[3] += d; state[4] += e;
}
 
std::stringstream stream;
for ( uint32_t i = 0; i < 20; ++i ) {
int8_t byte_value = static_cast<int8_t>(state[i / 4] >> ( 24 - ( i % 4 ) * 8));
stream << std::setfill('0') << std::setw(2) << std::hex << ( byte_value & 0xff );
}
return stream.str();
}
 
private:
std::vector<int8_t> add_padding(const std::string& message) {
std::vector<int8_t> bytes(message.begin(), message.end());
bytes.emplace_back(static_cast<uint8_t>(0x80));
 
uint32_t padding = BLOCK_LENGTH - ( bytes.size() % BLOCK_LENGTH );
if ( padding < 8 ) {
padding += BLOCK_LENGTH;
}
bytes.resize(bytes.size() + padding - 8, static_cast<int8_t>(0x0));
 
const uint64_t bit_length = 8 * message.length();
for ( int32_t i = 7; i >= 0; --i ) {
bytes.emplace_back(static_cast<int8_t>(bit_length >> ( 8 * i )));
}
return bytes;
}
 
const uint32_t BLOCK_LENGTH = 64;
};
 
int main() {
SHA1 sha1;
std::cout << sha1.message_digest("Rosetta Code") << std::endl;
}
</syntaxhighlight>
{{ out }}
<pre>
48c98f7e5a6e736d790ab740dfc3f51a61abe2b5
</pre>
 
=={{header|Caché ObjectScript}}==
Line 1,749 ⟶ 1,831:
=={{header|Java}}==
The solution to this task would be a small modification to [[MD5#Java|MD5]] (replacing "MD5" with "SHA-1" as noted [http://docs.oracle.com/javase/7/docs/technotes/guides/security/StandardNames.html#MessageDigest here]).
 
===Implementation===
A direct implementation of the SHA-1 algorithm.
<syntaxhighlight lang="java">
import java.nio.charset.StandardCharsets;
import java.util.Arrays;
 
public final class SHA1Task {
 
public static void main(String[] args) {
System.out.println(SHA1.messageDigest("Rosetta Code"));
}
 
}
 
final class SHA1 {
public static String messageDigest(String message) {
int[] state = { 0x67452301, 0xefcdab89, 0x98badcfe, 0x10325476, 0xc3d2e1f0 };
byte[] bytes = addPadding(message);
for ( int i = 0; i < bytes.length / BLOCK_LENGTH; i++ ) {
int[] values = new int[80];
for ( int j = 0; j < BLOCK_LENGTH; j++ ) {
values[j / 4] |= ( bytes[i * BLOCK_LENGTH + j] & 0xff ) << ( ( 3 - j % 4 ) * 8 );
}
for ( int j = 16; j < 80; j++ ) {
values[j] = Integer.rotateLeft(values[j - 3] ^ values[j - 8] ^ values[j - 14] ^ values[j - 16], 1);
}
int a = state[0], b = state[1], c = state[2], d = state[3], e = state[4];
int f = 0, k = 0;
for ( int j = 0; j < 80; j++ ) {
switch ( j / 20 ) {
case 0 -> { f = ( b & c ) | ( ~b & d ); k = 0x5a827999; }
case 1 -> { f = b ^ c ^ d; k = 0x6ed9eba1; }
case 2 -> { f = ( b & c ) | ( b & d ) | ( c & d ); k = 0x8f1bbcdc; }
case 3 -> { f = b ^ c ^ d; k = 0xca62c1d6; }
}
 
int temp = Integer.rotateLeft(a, 5) + f + e + k + values[j];
e = d; d = c; c = Integer.rotateLeft(b, 30); b = a; a = temp;
}
state[0] += a; state[1] += b; state[2] += c; state[3] += d; state[4] += e;
}
StringBuilder result = new StringBuilder();
for ( int i = 0; i < 20; i++ ) {
result.append(String.format("%02x", ( state[i / 4] >>> 24 - ( i % 4 ) * 8 ) & 0xFF ));
}
return result.toString();
}
private static byte[] addPadding(String message) {
byte[] bytes = message.getBytes(StandardCharsets.UTF_8);
bytes = Arrays.copyOf(bytes, bytes.length + 1);
bytes[bytes.length - 1] = (byte) 0x80;
int padding = BLOCK_LENGTH - ( bytes.length % BLOCK_LENGTH );
if ( padding < 8 ) {
padding += BLOCK_LENGTH;
}
bytes = Arrays.copyOf(bytes, bytes.length + padding);
final long bitLength = message.length() * 8;
for ( int i = 0; i < 8; i++ ) {
bytes[bytes.length - 1 - i] = (byte) ( bitLength >>> ( 8 * i ) );
}
return bytes;
}
private static final int BLOCK_LENGTH = 64;
}
</syntaxhighlight>
{{ out }}
<pre>
48c98f7e5a6e736d790ab740dfc3f51a61abe2b5
</pre>
 
=={{header|Jsish}}==
Line 2,381 ⟶ 2,543:
</syntaxhighlight>
taken from [http://stackoverflow.com/questions/8051713/convert-a-string-to-a-byte-array-in-powershell-version-2 Stackoverflow] with a little modification
 
=={{header|Prolog}}==
{{works with|SWI-Prolog}}
 
SWI-Prolog has SHA1 hashing as the default in its <code>sha_hash</code> function.
<syntaxhighlight lang="Prolog">:- use_module(library(sha)).
sha_hex(Str,Hex):-
sha_hash(Str, Hash, []),
hash_atom(Hash, Hex).</syntaxhighlight>
<syntaxhighlight lang="Prolog">?- sha_hex("Rosetta Code",Hex).
Hex = '48c98f7e5a6e736d790ab740dfc3f51a61abe2b5'.</syntaxhighlight>
 
=={{header|PureBasic}}==
Line 2,961 ⟶ 3,134:
9e9aeefe5563845ec5c42c5630842048c0fc261b</syntaxhighlight>
 
=={{header|V (Vlang)}}==
<syntaxhighlight lang="v (vlang)">import crypto.sha1
 
fn main() {
Line 2,980 ⟶ 3,153:
{{libheader|Wren-crypto}}
{{libheader|Wren-fmt}}
<syntaxhighlight lang="ecmascriptwren">import "./crypto" for Sha1
import "./fmt" for Fmt
var strings = [
9,482

edits