๐Ÿ‘จโ€๐Ÿ’ป For Developers

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:

1๏ธโƒฃ

Copy the Code

Copy our Luhn algorithm implementation

2๏ธโƒฃ

Paste in Your Project

Add to your JavaScript/Python/PHP file

3๏ธโƒฃ

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 NumberDOBGenderStatus
85010112340841985-01-01FemaleValid
90020256780931990-02-02FemaleValid
95030312340861995-03-03MaleValid
00010112340852000-01-01FemaleValid
1234567890123--Invalid

โœ… Best Practices for Developers

โœ“
Always validate on backend - Never trust client-side validation only
โœ“
Use test IDs only - Never use real citizen data in development
โœ“
Add clear disclaimers - Label test environments to avoid confusion
โœ“
Implement rate limiting - Protect your validation endpoints
โœ“
Log validation attempts - Monitor for suspicious activity
โœ“
Cache validation results - Improve performance for repeated checks