Wednesday, May 13, 2026

Educational Java CRC32 Key Generator & Validator

 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

ConceptPurpose
CRC32integrity verification
XOR maskinglightweight obfuscation
Base32 encodingreadable validation text
Scramblingstructure hiding
Embedded validationself-checking serials
Recalculationauthenticity 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 

No comments:

Post a Comment