The Perl Toolchain Summit needs more sponsors. If your company depends on Perl, please support this very important event.
NAME
    Business::BR::RG - Perl module to test for correct RG numbers

SYNOPSIS
    use Business::BR::RG;

    print "ok " if test_rg('390.533.447-05'); # prints 'ok ' print "bad "
    unless test_rg('231.002.999-00'); # prints 'bad '

DESCRIPTION
    The RG number is an identification number of Brazilian citizens emitted
    by the Department of Public Safety, which is called "Secretaria de
    Segurança Pública (SSP)".

    RG stands for "Cadastro Geral" because is valid in all brazil territory.
    May be use as passport to Argentina, Paraguay, Uruguay and Chile.

    The RG is comprised of a base of 8 digits and one check digit. It is
    usually written like '12.002.999-0' so as to be more human-readable.

    This module provides "test_rg" for checking that a RG number is
    *correct*. Here a *correct RG number* means

    *   it is 9 digits long

    *   it satisfies the check equation mentioned below

    Before checking, any non-digit letter is stripped, making it easy to
    test formatted entries like '21.002.999-00' and entries with extra
    blanks like ' 99.221.222-00 '. Except the letter X, because it's
    represents the number 10.

    test_rg
        test_rg('39.985.676-X') # incorrect RG, returns 0 test_rg('
        39.985.676-6 ') # is ok, returns 1 test_rg('123') # nope, returns
        undef

        Tests whether a RG number is correct. Before testing, any non-digit
        [except X, no matter its case] character is stripped. Then it is
        expected to be 9 digits long and to satisfy check equation which
        validate the check digit. See "THE CHECK EQUATIONS".

        The policy to get rid of '.' and '-' is very liberal. It indeeds
        discards anything that is not a digit (0, 1, ..., 9, or X) or
        letter. That is handy for discarding spaces as well

        test_rg(' 39.985.676-6 ') # is ok, returns 1

        But extraneous inputs like '3.9.9 8w5.6w7h6?6' are also accepted. If
        you are worried about this kind of input, just check against a
        regex:

        warn "bad RG: only digits (9) expected" unless ($rg =~
        /^\d{8}(\d|x)$/i);

        warn "bad RG: does not match mask '__.___.___-_'" unless ($rg =~
        /^\d{2}\.\d{3}\.\d{3}-(\d|x)$/i);

        NOTE. Integer numbers like 1234567 with fewer than 8 digits will be
        normalized (eg. to "001234567") before testing.

    canon_rg
        canon_rg(99); # returns '000000099' canon_rg('99.999.999-9'); #
        returns '999999999'

        Brings a candidate for a RG number to a canonical form. In case, the
        argument is an integer, it is formatted to at least 9 digits.
        Otherwise, it is stripped of any non-alphanumeric [again, except x]
        characters and returned as it is.

    format_rg
        format_rg('00000000'); # returns '00.000.000-0'

        Formats its input into '00.000.000-0' mask. First, the argument is
        canon'ed and then dots and hyphen are added to the first 9 digits of
        the result. So you can call format_rg even when its already
        formated.

    parse_rg
        ($base, $dv) = parse_rg($rg); $hashref = parse_rg('99.222.111-0'); #
        { base => '99222111', dv => '0' }

        Splits a candidate for RG number into base and check digits (dv -
        dÃgitos de verificação). It canon's the argument before splitting
        it into 8- and 1-digit parts. In a list context, returns a
        two-element list with the base and the check digits. In a scalar
        context, returns a hash ref with keys 'base' and 'dv' and associated
        values.

    random_rg
        $rand_rg = random_rg($valid);

        $correct_rg = random_rg(); $rg = random_rg(1); # also a correct RG
        $bad_rg = random_rg(0); # an incorrect RG

        Generates a random RG. If $valid is omitted or 1, it is guaranteed
        to be *correct*. If $valid is 0, it is guaranteed to be *incorrect*.
        This function is intented for mass test. (Use it wisely.)

        The implementation is simple: just generate a 8-digits random
        number, hopefully with a uniform distribution and then compute the
        check digits. If $valid==0, the check digits are computed not to
        satisfy the check equations.

  EXPORT
    "test_rg" is exported by default. "canon_rg", "format_rg", "parse_rg"
    and "random_rg" can be exported on demand.

THE CHECK EQUATIONS
    A correct RG number has one check digit which are computed from the base
    8 first digits. Consider the RG number written as 9 digits

    c[1] c[2] c[3] c[4] c[5] c[6] c[7] c[8] dv[1]

    To check whether a RG is correct or not, it has to satisfy the check
    equations:

    c[1]*2 + c[2]*3 + c[3]*4 + c[4]*5 + c[5]*6 + c[6]*7 + c[7]*8 + c[8]*9 +
    dv[9] * 100 = 0 (mod 11)

BUGS
    until now I do not found any RG that has less than 8 digits. But, I
    guess, old people still have it. For now, this is the only way that I
    found to check RG. If you found any bug, feel free to send e-mail, open
    an issue on github or open a RT.

SEE ALSO
    Note that this module only tests correctness. It doesn't enter the merit
    whether the RG number actually exists at the Brazilian government
    databases.

    Please reports bugs via CPAN RT or github.

    <http://github.com/renatocron/>

    You may be interested too in validation of CPF/CNPJ. So you can look at:

    Business::BR::CNPJ

    Business::BR::CPF

    You should too make a search about the Business::BR namespace.

SUPPORT
  Perldoc
    You can find documentation for this module with the perldoc command (to
    read this)

            perldoc Business\:\:BR\:\:RG

  Github
    If you want to contribute with the code, you can fork this module on
    github:

    <https://github.com/renatocron/Business--BR--RG>

    You can even report a issue.

AUTHOR
    Renato CRON, <rentocron@cpan.org>

COPYRIGHT AND LICENSE
    Copyright (C) 2011 by Renato CRON

    This library is free software; you can redistribute it and/or modify it
    under the same terms as Perl itself, either Perl version 5.10.1 or, at
    your option, any later version of Perl 5 you may have available.