CVV / CVC Calculator
Calculate CVV, CVV2, and iCVV values from card data and a 128-bit Card Verification Key. The same algorithm is used by Visa (CVV) and Mastercard (CVC) — only the keys differ.
Use test data only. All calculations run locally in your browser — PayProbe never sees, transmits, or stores your PAN, CVV, keys, PINs, or cryptographic inputs. How we handle data →
Algorithm
Input block = PAN ‖ expiry (YYMM) ‖ service code, zero-padded to 32 decimal digits.
Step 1 — DES-encrypt Block 1 (left 8 bytes) under K1 (CVK-A, left half of CVK).
Step 2 — XOR result with Block 2 (right 8 bytes).
Step 3 — 3DES-encrypt result with the full CVK (K1-K2-K1).
Step 4 — Decimate: collect digits 0–9 left to right, then A–F → 0–5; take leftmost 3 digits.
CVV2 and iCVV use the identical algorithm but with a fixed service code (000 for CVV2, 999 for iCVV), making the three values distinct for the same card.
# CVV / CVC Calculator — 3DES-based card verification value
# Requires: pip install pycryptodome
from Crypto.Cipher import DES3
from Crypto.Util.Padding import pad
def des3_encrypt_ecb(key: bytes, data: bytes) -> bytes:
cipher = DES3.new(key, DES3.MODE_ECB)
return cipher.encrypt(data)
def compute_cvv(pan: str, expiry: str, service_code: str, cvk_hex: str) -> str:
"""Compute CVV/CVC. expiry = YYMM, service_code = 3 digits."""
cvk = bytes.fromhex(cvk_hex)
key1, key2 = cvk[:8], cvk[8:16]
# Build two 8-byte data blocks
data = (pan + expiry + service_code).ljust(32, "0")
block1 = bytes.fromhex(data[:16])
block2 = bytes.fromhex(data[16:32])
# Step 1: encrypt block1 with key1
enc = des3_encrypt_ecb(key1, block1)
# Step 2: XOR with block2, encrypt with key2 then key1
xored = bytes(a ^ b for a, b in zip(enc, block2))
enc2 = des3_encrypt_ecb(key2, xored)
enc3 = des3_encrypt_ecb(key1, enc2)
# Extract digits then non-digits (converted)
result = enc3.hex().upper()
digits = [c for c in result if c.isdigit()]
non_digits = [str(ord(c) - ord("A")) for c in result if not c.isdigit()]
cvv_chars = (digits + non_digits)[:3]
return "".join(cvv_chars)
# Example
pan, expiry, sc = "4111111111111111", "2512", "101"
cvk = "0123456789ABCDEF0123456789ABCDEF"
print(f"CVV1: {compute_cvv(pan, expiry, sc, cvk)}")
# CVV2 uses service_code="000"
print(f"CVV2: {compute_cvv(pan, expiry, '000', cvk)}")
How card verification values work
The CVV/CVC is a cryptographic check value derived by the issuer from the PAN, expiry date, and service code using a pair of secret CVKs (Card Verification Keys) under Triple-DES. CVV1 is encoded on the magnetic stripe, CVV2 is the printed value used for card-not-present transactions, and the iCVV is a chip variant with a different service code so stripe data cannot be cloned to a chip. Because the keys are secret to the issuer, only the issuer (or its personalisation bureau) can compute the value for a real card.
This calculator demonstrates that algorithm so engineers can understand and test issuer-side and HSM verification logic. It is meaningful only with test PANs and test CVKs: enter a sandbox key set and a synthetic PAN and it shows how the value is produced. Without the genuine issuer keys — which are never exposed — it cannot produce a working CVV for any real card, and everything runs locally in your browser.
Why iCVV and CVV2 differ
A frequent source of confusion is that the same card yields different values across stripe, chip, and the printed CVV2. That is by design: the differing service code fed into the algorithm changes the result, which is precisely what stops magnetic-stripe data from being replayed onto a chip transaction.