Developer Guide
Complete documentation for integrating SA ID generation and validation into your applications
๐ Quick Start
Integrate SA ID validation into your project in 3 simple steps:
Copy the Code
Copy our Luhn algorithm implementation
Paste in Your Project
Add to your JavaScript/Python/PHP file
Start Validating
Call the function with any SA ID
๐ JavaScript Implementation
Complete JavaScript code for SA ID validation and generation:
// ==================== SA ID VALIDATION (JavaScript) ====================
/**
* Calculate Luhn check digit for SA ID
* @param {string} idWithoutCheck - First 12 digits of SA ID
* @returns {number} - The check digit (0-9)
*/
function calculateLuhnCheckDigit(idWithoutCheck) {
let sum = 0;
for (let i = idWithoutCheck.length - 1; i >= 0; i--) {
let digit = parseInt(idWithoutCheck[i]);
if ((idWithoutCheck.length - 1 - i) % 2 === 1) {
digit = digit * 2;
if (digit > 9) digit = digit - 9;
}
sum += digit;
}
return (10 - (sum % 10)) % 10;
}
/**
* Validate a complete SA ID number
* @param {string} fullId - Complete 13-digit SA ID
* @returns {boolean} - True if valid, false otherwise
*/
function validateSAID(fullId) {
if (!/^\d{13}$/.test(fullId)) return false;
const idWithoutCheck = fullId.substring(0, 12);
const providedCheckDigit = parseInt(fullId[12]);
const calculatedCheckDigit = calculateLuhnCheckDigit(idWithoutCheck);
return providedCheckDigit === calculatedCheckDigit;
}
/**
* Extract information from SA ID
* @param {string} id - Complete 13-digit SA ID
* @returns {object} - ID information
*/
function decodeSAID(id) {
if (!validateSAID(id)) return null;
const yearPrefix = parseInt(id.substring(0,2));
const year = yearPrefix > 24 ? 1900 + yearPrefix : 2000 + yearPrefix;
const month = parseInt(id.substring(2,4));
const day = parseInt(id.substring(4,6));
const genderCode = parseInt(id.substring(6,10));
const gender = genderCode < 5000 ? "Female" : "Male";
const citizen = id[10] === '0' ? "Citizen" : "Permanent Resident";
return { year, month, day, gender, citizen };
}
// Example usage
const id = "8501011234084";
console.log(validateSAID(id)); // true
console.log(decodeSAID(id)); // { year: 1985, month: 1, day: 1, gender: "Female", citizen: "Citizen" }
๐ Python Implementation
# ==================== SA ID VALIDATION (Python) ====================
def calculate_luhn_check_digit(id_without_check: str) -> int:
"""
Calculate Luhn check digit for SA ID
"""
total = 0
for i, digit in enumerate(reversed(id_without_check)):
n = int(digit)
if i % 2 == 1:
n = n * 2
if n > 9:
n = n - 9
total += n
return (10 - (total % 10)) % 10
def validate_sa_id(full_id: str) -> bool:
"""
Validate a complete SA ID number
"""
if not full_id.isdigit() or len(full_id) != 13:
return False
id_without_check = full_id[:12]
provided_check = int(full_id[12])
calculated_check = calculate_luhn_check_digit(id_without_check)
return provided_check == calculated_check
def decode_sa_id(full_id: str) -> dict:
"""
Extract information from SA ID
"""
if not validate_sa_id(full_id):
return None
year_prefix = int(full_id[0:2])
year = 1900 + year_prefix if year_prefix > 24 else 2000 + year_prefix
month = int(full_id[2:4])
day = int(full_id[4:6])
gender_code = int(full_id[6:10])
gender = "Female" if gender_code < 5000 else "Male"
citizen = "Citizen" if full_id[10] == '0' else "Permanent Resident"
return {
"year": year,
"month": month,
"day": day,
"gender": gender,
"citizen": citizen
}
# Example usage
id_number = "8501011234084"
print(validate_sa_id(id_number)) # True
print(decode_sa_id(id_number)) # {'year': 1985, 'month': 1, 'day': 1, 'gender': 'Female', 'citizen': 'Citizen'}
๐ PHP Implementation
<?php
// ==================== SA ID VALIDATION (PHP) ====================
/**
* Calculate Luhn check digit for SA ID
*/
function calculateLuhnCheckDigit($idWithoutCheck) {
$sum = 0;
$len = strlen($idWithoutCheck);
for ($i = $len - 1; $i >= 0; $i--) {
$digit = (int)$idWithoutCheck[$i];
if (($len - 1 - $i) % 2 == 1) {
$digit = $digit * 2;
if ($digit > 9) $digit = $digit - 9;
}
$sum += $digit;
}
return (10 - ($sum % 10)) % 10;
}
/**
* Validate a complete SA ID number
*/
function validateSAID($fullId) {
if (!preg_match('/^\d{13}$/', $fullId)) return false;
$idWithoutCheck = substr($fullId, 0, 12);
$providedCheck = (int)$fullId[12];
$calculatedCheck = calculateLuhnCheckDigit($idWithoutCheck);
return $providedCheck === $calculatedCheck;
}
/**
* Extract information from SA ID
*/
function decodeSAID($fullId) {
if (!validateSAID($fullId)) return null;
$yearPrefix = (int)substr($fullId, 0, 2);
$year = $yearPrefix > 24 ? 1900 + $yearPrefix : 2000 + $yearPrefix;
$month = (int)substr($fullId, 2, 2);
$day = (int)substr($fullId, 4, 2);
$genderCode = (int)substr($fullId, 6, 4);
$gender = $genderCode < 5000 ? "Female" : "Male";
$citizen = $fullId[10] == '0' ? "Citizen" : "Permanent Resident";
return [
'year' => $year,
'month' => $month,
'day' => $day,
'gender' => $gender,
'citizen' => $citizen
];
}
// Example usage
$id = "8501011234084";
var_dump(validateSAID($id)); // bool(true)
print_r(decodeSAID($id)); // Array with ID information
?>
โ Java Implementation
// ==================== SA ID VALIDATION (Java) ====================
public class SAIDValidator {
/**
* Calculate Luhn check digit for SA ID
*/
public static int calculateLuhnCheckDigit(String idWithoutCheck) {
int sum = 0;
int len = idWithoutCheck.length();
for (int i = len - 1; i >= 0; i--) {
int digit = Character.getNumericValue(idWithoutCheck.charAt(i));
if ((len - 1 - i) % 2 == 1) {
digit = digit * 2;
if (digit > 9) digit = digit - 9;
}
sum += digit;
}
return (10 - (sum % 10)) % 10;
}
/**
* Validate a complete SA ID number
*/
public static boolean validateSAID(String fullId) {
if (!fullId.matches("\\d{13}")) return false;
String idWithoutCheck = fullId.substring(0, 12);
int providedCheck = Character.getNumericValue(fullId.charAt(12));
int calculatedCheck = calculateLuhnCheckDigit(idWithoutCheck);
return providedCheck == calculatedCheck;
}
/**
* Extract information from SA ID
*/
public static SAIDInfo decodeSAID(String fullId) {
if (!validateSAID(fullId)) return null;
int yearPrefix = Integer.parseInt(fullId.substring(0, 2));
int year = yearPrefix > 24 ? 1900 + yearPrefix : 2000 + yearPrefix;
int month = Integer.parseInt(fullId.substring(2, 4));
int day = Integer.parseInt(fullId.substring(4, 6));
int genderCode = Integer.parseInt(fullId.substring(6, 10));
String gender = genderCode < 5000 ? "Female" : "Male";
String citizen = fullId.charAt(10) == '0' ? "Citizen" : "Permanent Resident";
return new SAIDInfo(year, month, day, gender, citizen);
}
// Example usage
public static void main(String[] args) {
String id = "8501011234084";
System.out.println(validateSAID(id)); // true
}
}
class SAIDInfo {
// Getters and constructor
}
๐ท C# / .NET Implementation
// ==================== SA ID VALIDATION (C#) ====================
using System;
using System.Text.RegularExpressions;
public class SAIDValidator
{
/// <summary>
/// Calculate Luhn check digit for SA ID
/// </summary>
public static int CalculateLuhnCheckDigit(string idWithoutCheck)
{
int sum = 0;
int len = idWithoutCheck.Length;
for (int i = len - 1; i >= 0; i--)
{
int digit = int.Parse(idWithoutCheck[i].ToString());
if ((len - 1 - i) % 2 == 1)
{
digit = digit * 2;
if (digit > 9) digit = digit - 9;
}
sum += digit;
}
return (10 - (sum % 10)) % 10;
}
/// <summary>
/// Validate a complete SA ID number
/// </summary>
public static bool ValidateSAID(string fullId)
{
if (!Regex.IsMatch(fullId, @"^\d{13}$")) return false;
string idWithoutCheck = fullId.Substring(0, 12);
int providedCheck = int.Parse(fullId[12].ToString());
int calculatedCheck = CalculateLuhnCheckDigit(idWithoutCheck);
return providedCheck == calculatedCheck;
}
/// <summary>
/// Extract information from SA ID
/// </summary>
public static SAIDInfo DecodeSAID(string fullId)
{
if (!ValidateSAID(fullId)) return null;
int yearPrefix = int.Parse(fullId.Substring(0, 2));
int year = yearPrefix > 24 ? 1900 + yearPrefix : 2000 + yearPrefix;
int month = int.Parse(fullId.Substring(2, 2));
int day = int.Parse(fullId.Substring(4, 2));
int genderCode = int.Parse(fullId.Substring(6, 4));
string gender = genderCode < 5000 ? "Female" : "Male";
string citizen = fullId[10] == '0' ? "Citizen" : "Permanent Resident";
return new SAIDInfo(year, month, day, gender, citizen);
}
}
public class SAIDInfo
{
public int Year { get; set; }
public int Month { get; set; }
public int Day { get; set; }
public string Gender { get; set; }
public string Citizen { get; set; }
}
๐ API Reference
Use our free API endpoints for SA ID validation (Coming Soon):
GET https://api.sa-id.com/validate/{id}
Validate an SA ID number
Response: { "valid": true, "data": { "dob": "1985-01-01", "gender": "Female" } }
GET https://api.sa-id.com/generate
Generate a random valid SA ID
Response: { "id": "8501011234084", "barcode": "base64..." }
POST https://api.sa-id.com/generate/bulk
Generate multiple SA IDs
Body: { "count": 10, "gender": "female" }
โ ๏ธ Note: API is currently in development. Contact us for early access.
๐งช Test IDs for Development
Use these test IDs for your development and testing:
| ID Number | DOB | Gender | Status |
|---|---|---|---|
| 8501011234084 | 1985-01-01 | Female | Valid |
| 9002025678093 | 1990-02-02 | Female | Valid |
| 9503031234086 | 1995-03-03 | Male | Valid |
| 0001011234085 | 2000-01-01 | Female | Valid |
| 1234567890123 | - | - | Invalid |