The Hash Stamper

An easy Python interview practice problem on DataDriven. Write the Python and run it against test cases, with instant feedback.

Domain
Python
Difficulty
easy
Seniority
L3
Asked in
Rally Health

Problem

Our seeds are free-form UTF-8 text, accented characters included, and a given seed has to produce the same token on every machine. We stamp it by taking the SHA-256 hex digest of the seed and keeping its first length characters.

One input, one irreversible output - the foundation of every secret.

Example 1

Input:

seed = "secret", length = 8

Output:

"2bb80d53"

Example 2

Input:

seed = "password", length = 4

Output:

"5e88"

Worked solution and explanation

What this is really testing

Strip the costume and this is a str/bytes boundary drill wearing a token-generation hat. Anyone can recite SHA-256. What separates candidates is knowing that hashlib eats bytes and hands back a str, and crossing that line on purpose. The trap is calling hashlib.sha256(seed) on a bare string, or grabbing .digest() when you needed .hexdigest(). Miss it and you either throw a TypeError at call time or return raw bytes that silently poison the idempotency key this digest was meant to stamp.

Where this shows up on the job

Deterministic tokens are the backbone of idempotency keys, cache busting and license stamping. One short function quietly probes three things. Do you know hashlib? Do you encode text to bytes before hashing? And do you know a SHA-256 hex digest is exactly 64 characters, so every length request is bounded?


Break down the requirements

Step 1: Encode the seed to bytes

hashlib constructors take bytes, not str. Use seed.encode('utf-8'): skipping it raises TypeError, and naming UTF-8 explicitly pins the byte representation. That way an accented seed like 'café' hashes the same on every machine, which is exactly the property the statement leads with.

Step 2: Take the SHA-256 hex digest

hashlib.sha256(...).hexdigest() returns a 64-character lowercase hex string. The move that matters is .hexdigest(), not .digest(). The latter returns raw bytes, and slicing bytes gives you bytes, which breaks the string contract the examples show. SHA-256 is the right default: available everywhere, fast, and not broken the way MD5 and SHA-1 are for security uses.

Step 3: Slice the first length characters

Slicing never raises on an out-of-range stop, so digest[:length] returns the whole digest when length exceeds 64. Every request asks for at least one character, so there is no zero guard to write. Even so, saying the 64-character ceiling out loud is the kind of real constraint an interviewer notices.


The solution

Encode, hash, hex, slice
import hashlib

def generate_password_from_seed(seed: str, length: int) -> str:
    digest = hashlib.sha256(seed.encode('utf-8')).hexdigest()
    return digest[:length]

Common follow-up questions