This version is a simplified educational serial-key system that uses:
- CRC32 validation,
- XOR masking,
- scrambling,
- Base32-style encoding,
- embedded integrity data.
It is designed to demonstrate how many classic offline product-key systems worked.
How The System Works
Random Characters
↓
CRC32 Calculation
↓
XOR Secret Constant
↓
Encode CRC32
↓
Embed Validation Data
↓
Scramble
↓
Format Product Key
Validator later:
Remove Formatting
↓
Unscramble
↓
Extract CRC Section
↓
Recalculate CRC32
↓
Compare Results
1. KeyGenerator.java
import java.util.Random;
import java.util.zip.CRC32;
public class KeyGenerator {
static final String ALPHABET =
"ABCDEFGHJKLMNPQRSTUVWXYZ23456789";
static final int SECRET_XOR = 0x1D8DF;
static Random random = new Random();
public static void main(String[] args) {
// Step 1: Generate random section
String randomPart = generateRandomText(12);
// Step 2: Calculate CRC32
long crc = calculateCRC32(randomPart);
// Step 3: XOR mask
crc = crc ^ SECRET_XOR;
// Step 4: Encode CRC
String crcText = encodeCRC(crc);
// Step 5: Combine
String fullKey = randomPart + crcText;
// Step 6: Scramble
fullKey = scramble(fullKey);
// Step 7: Format
fullKey = formatKey(fullKey);
System.out.println("Generated Key:");
System.out.println(fullKey);
}
static String generateRandomText(int length) {
StringBuilder sb = new StringBuilder();
for (int i = 0; i < length; i++) {
sb.append(
ALPHABET.charAt(
random.nextInt(ALPHABET.length())
)
);
}
return sb.toString();
}
static long calculateCRC32(String text) {
CRC32 crc = new CRC32();
crc.update(text.getBytes());
return crc.getValue();
}
static String encodeCRC(long value) {
char[] out = new char[6];
for (int i = 0; i < out.length; i++) {
int index =
(int)(value % ALPHABET.length());
out[i] = ALPHABET.charAt(index);
value /= ALPHABET.length();
}
return new String(out);
}
static String scramble(String text) {
char[] data = text.toCharArray();
swap(data, 1, 5);
swap(data, 2, 8);
swap(data, 4, 14);
swap(data, 7, 15);
return new String(data);
}
static void swap(char[] data, int a, int b) {
char temp = data[a];
data[a] = data[b];
data[b] = temp;
}
static String formatKey(String key) {
StringBuilder sb = new StringBuilder();
for (int i = 0; i < key.length(); i++) {
sb.append(key.charAt(i));
if ((i + 1) % 4 == 0
&& i != key.length() - 1) {
sb.append('-');
}
}
return sb.toString();
}
}
2. KeyValidator.java
import java.util.Scanner;
import java.util.zip.CRC32;
public class KeyValidator {
static final String ALPHABET =
"ABCDEFGHJKLMNPQRSTUVWXYZ23456789";
static final int SECRET_XOR = 0x1D8DF;
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
System.out.println("Enter key:");
String key = scanner.nextLine();
boolean valid = validate(key);
if (valid) {
System.out.println("VALID KEY");
} else {
System.out.println("INVALID KEY");
}
}
static boolean validate(String key) {
// Remove dashes
key = key.replace("-", "");
// Unscramble
key = unscramble(key);
// Split sections
String randomPart = key.substring(0, 12);
String crcPart = key.substring(12, 18);
// Recalculate CRC32
long crc = calculateCRC32(randomPart);
// XOR again
crc = crc ^ SECRET_XOR;
// Encode expected CRC
String expected = encodeCRC(crc);
// Compare
return expected.equals(crcPart);
}
static long calculateCRC32(String text) {
CRC32 crc = new CRC32();
crc.update(text.getBytes());
return crc.getValue();
}
static String encodeCRC(long value) {
char[] out = new char[6];
for (int i = 0; i < out.length; i++) {
int index =
(int)(value % ALPHABET.length());
out[i] = ALPHABET.charAt(index);
value /= ALPHABET.length();
}
return new String(out);
}
static String unscramble(String text) {
char[] data = text.toCharArray();
// Reverse swaps
swap(data, 7, 15);
swap(data, 4, 14);
swap(data, 2, 8);
swap(data, 1, 5);
return new String(data);
}
static void swap(char[] data, int a, int b) {
char temp = data[a];
data[a] = data[b];
data[b] = temp;
}
}
Example Output
Generated Key:
A7QK-9PLX-W2RM-TJ8N-4K
Validator:
Enter key:
A7QK-9PLX-W2RM-TJ8N-4K
VALID KEY
Modified key:
A7QK-9PLX-W2RM-TJ8N-5K
Result:
INVALID KEY
Educational Concepts Demonstrated
| Concept | Purpose |
|---|---|
| CRC32 | integrity verification |
| XOR masking | lightweight obfuscation |
| Base32 encoding | readable validation text |
| Scrambling | structure hiding |
| Embedded validation | self-checking serials |
| Recalculation | authenticity checking |
Important Note
This project is educational only.
It demonstrates:
- classic offline key validation ideas,
- integrity algorithms,
- serial formatting concepts,
- and historical DRM-style design patterns.
It is not secure modern licensing or cryptography.
github: https://github.com/stark9000/Educational-Java-CRC32-Key-Generator-Validator