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. Dynamic CVV (dCVV) uses a different, ATC-based algorithm and is not computed here.
Follows Visa CVV / Mastercard CVC algorithmCVV1, CVV2, iCVV·verified Oct 2026· double-checked Oct 2026— reproduces the published example (PAN 4123456789012345, 8701, 101 → 561) and an independent DES implementation
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 the result with the full CVK (K1-K2-K1): DES-encrypt under K1, DES-decrypt under K2, DES-encrypt under 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. The iCVV replaces the CVV in the chip's Track 2 Equivalent Data (tag 57).
Not covered: dynamic CVV (dCVV, contactless magstripe mode) is a different algorithm that also takes the Application Transaction Counter, so its value changes per transaction; this tool does not compute it.
# Visa CVV / Mastercard CVC — the published worked example
# Requires: pip install pycryptodome
from Crypto.Cipher import DES
def des_enc(k: bytes, b: bytes) -> bytes: return DES.new(k, DES.MODE_ECB).encrypt(b)
def des_dec(k: bytes, b: bytes) -> bytes: return DES.new(k, DES.MODE_ECB).decrypt(b)
def compute_cvv(pan: str, expiry_yymm: str, service_code: str, cvk_hex: str) -> str:
cvk = bytes.fromhex(cvk_hex)
k1, k2 = cvk[:8], cvk[8:16] # CVK-A, CVK-B
data = (pan + expiry_yymm + service_code).ljust(32, "0")[:32]
b1, b2 = bytes.fromhex(data[:16]), bytes.fromhex(data[16:])
x = bytes(a ^ b for a, b in zip(des_enc(k1, b1), b2)) # E_K1(B1) XOR B2
r = des_enc(k1, des_dec(k2, des_enc(k1, x))) # E_K1(D_K2(E_K1(x)))
h = r.hex().upper()
digits = [c for c in h if c.isdigit()] + [str(int(c, 16) - 10) for c in h if not c.isdigit()]
return "".join(digits[:3])
cvk = "0123456789ABCDEFFEDCBA9876543210"
print("CVV1:", compute_cvv("4123456789012345", "8701", "101", cvk)) # CVV1: 561
print("CVV2:", compute_cvv("4123456789012345", "8701", "000", cvk)) # CVV2: 636
print("iCVV:", compute_cvv("4123456789012345", "8701", "999", cvk)) # iCVV: 651
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 the chip variant — computed with service code 999 and placed in the chip's Track 2 Equivalent Data — so track data read from a chip cannot be written onto a magnetic stripe and pass the stripe CVV check. 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 Track 2 Equivalent Data skimmed from a chip from being cloned onto a counterfeit magnetic-stripe card: the issuer expects the stripe CVV, not the iCVV, on a swiped transaction.