Python Argon2 Hash Code Example (Online Runner)
Python Argon2id/Argon2i/Argon2d hashing examples with iterations, memory, parallelism, salt encoding, and secret inputs.
Online calculator: use the site Argon2 text tool.
Note: This snippet requires locally installed dependencies and will not run in the online runner.
Calculation method
The online tool exposes Argon2 variant, iterations, memory (KiB), parallelism, hash length, salt encoding, and an optional
secret. When the salt field is left blank the UI generates a random 16-byte salt; the helper below mirrors that behavior.
The Python example uses argon2-cffi's low-level API so the parameters map 1:1.
Install the dependency first: pip install argon2-cffi.
Implementation notes
- Package:
argon2-cffiexposes the low-level API sotime_cost,memory_cost(KiB), andparallelismmap directly. - Implementation: the helper returns both the raw hash (hex) and the encoded Argon2 string, which already includes the salt, version, and parameters for verification.
- Notes: Argon2id is the recommended default for password hashing. Use a unique random salt per password; the optional
secretacts like a server-side pepper and is not stored in the encoded hash.
python
import base64
import secrets
from typing import Literal, Optional
from argon2.low_level import Type, hash_secret, hash_secret_raw
Variant = Literal["argon2id", "argon2i", "argon2d"]
SaltEncoding = Literal["base64", "hex", "text"]
def _variant_type(variant: Variant) -> Type:
return {"argon2id": Type.ID, "argon2i": Type.I, "argon2d": Type.D}[variant]
def _decode_salt(value: str, encoding: SaltEncoding) -> bytes:
if not value:
return secrets.token_bytes(16)
if encoding == "hex":
return bytes.fromhex(value)
if encoding == "text":
return value.encode("utf-8")
return base64.b64decode(value)
def argon2_text(
text: str,
variant: Variant = "argon2id",
iterations: int = 3,
memory_kib: int = 65536,
parallelism: int = 1,
hash_length: int = 32,
salt: str = "",
salt_encoding: SaltEncoding = "base64",
secret: Optional[str] = None,
) -> tuple[str, str]:
salt_bytes = _decode_salt(salt, salt_encoding)
secret_bytes = secret.encode("utf-8") if secret else None
variant_type = _variant_type(variant)
raw = hash_secret_raw(
text.encode("utf-8"),
salt=salt_bytes,
time_cost=iterations,
memory_cost=memory_kib,
parallelism=parallelism,
hash_len=hash_length,
type=variant_type,
secret=secret_bytes,
)
encoded = hash_secret(
text.encode("utf-8"),
salt=salt_bytes,
time_cost=iterations,
memory_cost=memory_kib,
parallelism=parallelism,
hash_len=hash_length,
type=variant_type,
secret=secret_bytes,
).decode("utf-8")
return raw.hex(), encoded
# Example usage
hex_hash, encoded = argon2_text(
"password",
variant="argon2id",
iterations=3,
memory_kib=65536,
parallelism=1,
hash_length=32,
salt="73616c74",
salt_encoding="hex",
)
print(hex_hash)
print(encoded)
# Alternate parameters (Argon2i + secret pepper).
hex_hash_i, encoded_i = argon2_text(
"password",
variant="argon2i",
iterations=4,
memory_kib=32768,
parallelism=2,
hash_length=32,
salt="c2FsdA==",
salt_encoding="base64",
secret="pepper",
)
print(hex_hash_i)
Complete script (implementation + tests)
python
from argon2.low_level import Type, hash_secret
def run_tests() -> None:
encoded = hash_secret(
secret=b"password",
salt=b"salt",
time_cost=2,
memory_cost=65536,
parallelism=1,
hash_len=32,
type=Type.ID,
).decode("utf-8")
assert encoded.startswith("$argon2id$"), "Argon2 encoded output mismatch"
print("All Argon2 tests passed.")
if __name__ == "__main__":
run_tests()