All Tools
Tools/CVV / CVC Calculator
🔐
EMV & ChipAvailable

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 →

CVK = left 8 bytes (CVK-A / K1) + right 8 bytes (CVK-B / K2)

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.

</> Code Implementation
# 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.

Something wrong or missing? Report a problem— we check reports against the specs and fix them.