Fairness
OPDuel Originals
Limbo
Plinko
Keno
Roulette
Mines
Blackjack
Roll
Dice
Provably Fair Blackjack
Blackjack uses an infinite deck where each card is drawn independently. Every draw has the same probability since the deck never depletes. The game generates all cards needed for the hand before play begins.
Verify Game Fairness
Deal Order
Cards are dealt one by one in this order: player, dealer, player, dealer. Any additional cards (hits, doubles, dealer draws) continue sequentially from the same generated list.
Game Rules
- Card values: Number cards are face value, face cards (J, Q, K) are worth 10, Aces are 1 or 11
- Dealer rules: Hits on 16 or less, stands on soft 17
- Doubling: Allowed on any first two cards, and after a split
- Splitting: You can only split once. You cannot hit on split aces
- Insurance: Available when dealer shows an Ace, costs half your bet, pays 2:1
- Natural blackjack push: If both you and the dealer have blackjack, the result is a push
- Dealer blackjack: If the dealer has natural blackjack, the hand ends immediately
- Side bets: Perfect Pairs and 21+3 are settled from the first 3 dealt cards (your two cards + dealer’s upcard)
The Algorithm
// Step 1: Generate card draws using HMAC-SHA256 RNG
const { getRandom } = createRandomGenerator(serverSeed, clientSeed, nonce);
// Step 2: Each card is drawn independently from a 52-card deck
const cardIndex = getRandom(52); // floor(float * 52)
const card = CARDS[cardIndex];
// Card deck (suits grouped per rank)
const CARDS = [
'♦2', '♥2', '♠2', '♣2',
'♦3', '♥3', '♠3', '♣3',
'♦4', '♥4', '♠4', '♣4',
'♦5', '♥5', '♠5', '♣5',
'♦6', '♥6', '♠6', '♣6',
'♦7', '♥7', '♠7', '♣7',
'♦8', '♥8', '♠8', '♣8',
'♦9', '♥9', '♠9', '♣9',
'♦10', '♥10', '♠10', '♣10',
'♦J', '♥J', '♠J', '♣J',
'♦Q', '♥Q', '♠Q', '♣Q',
'♦K', '♥K', '♠K', '♣K',
'♦A', '♥A', '♠A', '♣A',
];How It Works
- Generate floats - Using the same HMAC-SHA256 method as other OPDuel Originals, random floats between 0 and 1 are generated for each card needed
- Convert to index - Each float is multiplied by 52 and floored to produce an integer from 0-51
- Map to card - The index corresponds to a card in the deck array. Cards are dealt sequentially as the hand progresses: player, dealer, player, dealer, then any hits or dealer draws
Since the deck is infinite, the same card can appear multiple times in a hand.
Card Index Reference
| Index | Card | Index | Card | Index | Card | Index | Card |
|---|---|---|---|---|---|---|---|
| 0 | ♦2 | 16 | ♦6 | 32 | ♦10 | 48 | ♦A |
| 1 | ♥2 | 17 | ♥6 | 33 | ♥10 | 49 | ♥A |
| 2 | ♠2 | 18 | ♠6 | 34 | ♠10 | 50 | ♠A |
| 3 | ♣2 | 19 | ♣6 | 35 | ♣10 | 51 | ♣A |
| 4 | ♦3 | 20 | ♦7 | 36 | ♦J | ||
| 5 | ♥3 | 21 | ♥7 | 37 | ♥J | ||
| 6 | ♠3 | 22 | ♠7 | 38 | ♠J | ||
| 7 | ♣3 | 23 | ♣7 | 39 | ♣J | ||
| 8 | ♦4 | 24 | ♦8 | 40 | ♦Q | ||
| 9 | ♥4 | 25 | ♥8 | 41 | ♥Q | ||
| 10 | ♠4 | 26 | ♠8 | 42 | ♠Q | ||
| 11 | ♣4 | 27 | ♣8 | 43 | ♣Q | ||
| 12 | ♦5 | 28 | ♦9 | 44 | ♦K | ||
| 13 | ♥5 | 29 | ♥9 | 45 | ♥K | ||
| 14 | ♠5 | 30 | ♠9 | 46 | ♠K | ||
| 15 | ♣5 | 31 | ♣9 | 47 | ♣K |
Example
Given these inputs:
- Server Seed:
c5e7146c5863d7d647c93ffe7d4ec13fffbb7311108fab0c067d97bcc2b32d55 - Client Seed:
LuckyClientSeed777 - Nonce:
0
The floats generated: [0.25783150, 0.09994979, 0.81939594, 0.69399282, 0.54038320, ...]
Card 1 (Player): floor(0.25783150 × 52) = floor(13.41) = 13 → ♥5
Card 2 (Dealer): floor(0.09994979 × 52) = floor(5.20) = 5 → ♥3
Card 3 (Player): floor(0.81939594 × 52) = floor(42.61) = 42 → ♠Q
Card 4 (Dealer): floor(0.69399282 × 52) = floor(36.09) = 36 → ♦J
Card 5 (Next): floor(0.54038320 × 52) = floor(28.10) = 28 → ♦9Player hand: ♥5, ♠Q (15) | Dealer hand: ♥3, ♦J (13) | Next card: ♦9 (hit, double, or dealer draw)

