Every language
12 lenguajes, copy-ready. One at a time with syntax highlighting, or all inline.
JSJavaScript
// crypto.subtle is async — the Web Crypto API, secure contexts only
const digest = await crypto.subtle.digest('SHA-256',
new TextEncoder().encode('hello world'));
const hex = [...new Uint8Array(digest)]
.map((b) => b.toString(16).padStart(2, '0'))
.join('');
console.log(hex);Node has the sync one-liner: crypto.createHash('sha256').update(s).digest('hex').
TSTypeScript
async function sha256Hex(input: string): Promise<string> {
const digest = await crypto.subtle.digest(
'SHA-256',
new TextEncoder().encode(input),
);
return [...new Uint8Array(digest)]
.map((b) => b.toString(16).padStart(2, '0'))
.join('');
}padStart(2, '0') is load-bearing — toString(16) drops the leading zero on bytes under 0x10 and silently breaks the hex string.
GoGo
sum := sha256.Sum256([]byte("hello world"))
fmt.Println(hex.EncodeToString(sum[:])) // or just fmt.Printf("%x\n", sum)Sum256 returns a [32]byte array — sum[:] slices it into the []byte hex.EncodeToString wants.
RsRust
use sha2::{Digest, Sha256};
let hex = format!("{:x}", Sha256::digest(b"hello world"));
println!("{hex}");sha2 is the RustCrypto canonical crate. {:x} on the generic-array output renders lowercase hex directly — no manual byte loop.
PHPPHP
$hex = hash('sha256', 'hello world'); // 64-char hex string
$raw = hash('sha256', 'hello world', true); // 32 raw bytes
echo $hex, PHP_EOL;hash() is encoding-agnostic because PHP strings are byte strings. The third parameter true switches hex → raw output.
PyPython
import hashlib
hexdigest = hashlib.sha256(b'hello world').hexdigest()
raw = hashlib.sha256(b'hello world').digest() # bytes, len 32
print(hexdigest)The b'' literal is UTF-8 already; for runtime strings hash(s.encode()). hexdigest() and digest() are the same bytes, two renderings.
C#C#
using System.Security.Cryptography;
byte[] hash = SHA256.HashData("hello world"u8);
string hex = Convert.ToHexString(hash).ToLowerInvariant();
Console.WriteLine(hex);SHA256.HashData (.NET 5+) replaced the Create()/TransformFinalBlock dance. Convert.ToHexString returns UPPERCASE — lower it if your consumer expects the common lowercase.
JvJava
import java.nio.charset.StandardCharsets;
import java.security.MessageDigest;
import java.util.HexFormat;
byte[] hash = MessageDigest.getInstance("SHA-256")
.digest("hello world".getBytes(StandardCharsets.UTF_8));
String hex = HexFormat.of().formatHex(hash);Java 17+ HexFormat killed the hand-rolled %02x StringBuilder loop that haunted every older example.
SwSwift
import CryptoKit
let hex = SHA256.hash(data: Data("hello world".utf8))
.map { String(format: "%02x", $0) }
.joined()
print(hex)CryptoKit is Apple-platform; swift-crypto is the same API as a cross-platform Swift package. %02x — the zero-padding is what keeps the hex length at 64.
KtKotlin
import java.security.MessageDigest
import java.util.HexFormat
val hex = HexFormat.of().formatHex(
MessageDigest.getInstance("SHA-256")
.digest("hello world".toByteArray()),
)Same JVM MessageDigest; toByteArray() is UTF-8 by default in Kotlin.
RbRuby
require 'digest'
hex = Digest::SHA256.hexdigest('hello world')
puts hexDigest::SHA256.digest gives the 32 raw bytes; .hexdigest is the convention everyone else matches.
ZigZig
const std = @import("std");
pub fn main() !void {
var out: [std.crypto.hash.sha2.Sha256.digest_length]u8 = undefined;
std.crypto.hash.sha2.Sha256.hash("hello world", &out, .{});
std.debug.print("{s}\n", .{std.fmt.fmtSliceHexLower(&out)});
}The .{} options arg enables streaming mode for large inputs; init/update/final is the incremental API. fmtSliceHexLower formats without allocating.