Skip to content

Instantly share code, notes, and snippets.

@mhf-ir
Created November 24, 2017 09:48
Show Gist options
  • Save mhf-ir/c17374fae395a57c9f8e5fe7a92bbf23 to your computer and use it in GitHub Desktop.
Save mhf-ir/c17374fae395a57c9f8e5fe7a92bbf23 to your computer and use it in GitHub Desktop.
iranian sheba bank validation javascript | اعتبار سنجی کد شبا با جاوا اسکریپت
function iso7064Mod97_10(iban) {
var remainder = iban,
block;
while (remainder.length > 2){
block = remainder.slice(0, 9);
remainder = parseInt(block, 10) % 97 + remainder.slice(block.length);
}
return parseInt(remainder, 10) % 97;
}
function validateIranianSheba(str) {
var pattern = /IR[0-9]{24}/;
if (str.length !== 26) {
return false;
}
if (!pattern.test(str)) {
return false;
}
var newStr = str.substr(4);
var d1 = str.charCodeAt(0) - 65 + 10;
var d2 = str.charCodeAt(1) - 65 + 10;
newStr += d1.toString() + d2.toString() + str.substr(2, 2);
var remainder = iso7064Mod97_10(newStr);
if (remainder !== 1) {
return false;
}
return true;
};
console.log(validateIranianSheba('ENTER SHEBA NUMBER HERE IT\'SRETURN TRUE OR FALSE'));
@hasanparasteh
Copy link

hasanparasteh commented Feb 24, 2022

Here is the typescript version:

export function iso7064Mod97_10(iban: string): number {
    let remainder: string = iban;
    let block: string;

    while (remainder.length > 2) {
        block = remainder.slice(0, 9);
        remainder = parseInt(block, 10) % 97 + remainder.slice(block.length);
    }

    return parseInt(remainder, 10) % 97;
}

export function validateIranianSheba(iban: string): boolean {
    if (!iban.startsWith('IR')) {
        iban = 'IR' + iban;
    }

    const pattern = /IR[0-9]{24}/;

    if (iban.length !== 26) {
        return false;
    }

    if (!pattern.test(iban)) {
        return false;
    }

    let testString = iban.substring(4);
    const d1 = iban.charCodeAt(0) - 65 + 10;
    const d2 = iban.charCodeAt(1) - 65 + 10;
    testString += d1.toString() + d2.toString() + iban.substring(2, 4);

    if (iso7064Mod97_10(testString) !== 1) {
        return false;
    }
    return true;
}

@kasir-barati
Copy link

class-validator deocrator:

import {
    registerDecorator,
    ValidationArguments,
    ValidationOptions,
    ValidatorConstraint,
    ValidatorConstraintInterface,
} from 'class-validator';

export function IsValidIban(validationOptions?: ValidationOptions) {
    return function (object: Object, propertyName: string) {
        registerDecorator({
            name: 'IsValidIban',
            propertyName,
            async: false,
            target: object.constructor,
            options: validationOptions,
            validator: IsValidIbanConstraint,
        });
    };
}

@ValidatorConstraint({ name: 'IsValidIban', async: false })
export class IsValidIbanConstraint
    implements ValidatorConstraintInterface
{
    validate(
        value: string,
        validationArguments?: ValidationArguments,
    ): boolean | Promise<boolean> {
        return isValidIban(value);
    }

    defaultMessage(
        validationArguments?: ValidationArguments,
    ): string {
        return 'Entered IBAN - $value - is not a valid Iranian IBAN number';
    }
}

function isValidIban(iban: string): boolean {
    // Check Chartacters
    if (!/^IR\d{24}$/.test(iban)) return false;

    // Match And Capture (0) The Country Code, (1) The Check Digits, And (3) The Rest
    const code = iban.match(/^([A-Z]{2})(\d{2})([A-Z\d]+)$/);

    // Check Syntax And Length
    if (!code) {
        return false;
    }

    // // Rearrange country Code & Check Digits, Convert Chars To Ints
    let digits = (code[3] + code[1] + code[2]).replace(
        /[A-Z]/g,
        (letter) => {
            return String(letter.charCodeAt(0) - 55);
        },
    );

    // // Final Check
    return mod97(digits) === 1;
}

function mod97(string: string) {
    let checksum: string | number = string.slice(0, 2);
    let fragment: string;

    for (let offset = 2; offset < string.length; offset += 7) {
        fragment =
            String(checksum) + string.substring(offset, offset + 7);
        checksum = parseInt(fragment, 10) % 97;
    }

    return checksum;
}

@mahdihashemi88
Copy link

Here is the typescript version:

export function iso7064Mod97_10(iban: string): number {
    let remainder: string = iban;
    let block: string;

    while (remainder.length > 2) {
        block = remainder.slice(0, 9);
        remainder = parseInt(block, 10) % 97 + remainder.slice(block.length);
    }

    return parseInt(remainder, 10) % 97;
}

export function validateIranianSheba(iban: string): boolean {
    if (!iban.startsWith('IR')) {
        iban = 'IR' + iban;
    }

    const pattern = /IR[0-9]{24}/;

    if (iban.length !== 26) {
        return false;
    }

    if (!pattern.test(iban)) {
        return false;
    }

    let testString = iban.substring(4);
    const d1 = iban.charCodeAt(0) - 65 + 10;
    const d2 = iban.charCodeAt(1) - 65 + 10;
    testString += d1.toString() + d2.toString() + iban.substring(2, 2);

    if (iso7064Mod97_10(testString) !== 1) {
        return false;
    }
    return true;
}

the part you are creating test string at iban.substring(2, 2); is wrong! you should switch it to iban.substring(2, 4). the way the substr works is a little different than substring. substring expect the end in the second argument not length!

@hasanparasteh
Copy link

Here is the typescript version:

export function iso7064Mod97_10(iban: string): number {
    let remainder: string = iban;
    let block: string;

    while (remainder.length > 2) {
        block = remainder.slice(0, 9);
        remainder = parseInt(block, 10) % 97 + remainder.slice(block.length);
    }

    return parseInt(remainder, 10) % 97;
}

export function validateIranianSheba(iban: string): boolean {
    if (!iban.startsWith('IR')) {
        iban = 'IR' + iban;
    }

    const pattern = /IR[0-9]{24}/;

    if (iban.length !== 26) {
        return false;
    }

    if (!pattern.test(iban)) {
        return false;
    }

    let testString = iban.substring(4);
    const d1 = iban.charCodeAt(0) - 65 + 10;
    const d2 = iban.charCodeAt(1) - 65 + 10;
    testString += d1.toString() + d2.toString() + iban.substring(2, 2);

    if (iso7064Mod97_10(testString) !== 1) {
        return false;
    }
    return true;
}

the part you are creating test string at iban.substring(2, 2); is wrong! you should switch it to iban.substring(2, 4). the way the substr works is a little different than substring. substring expect the end in the second argument not length!

Thanks for your contribution. I fixed that problem.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment