1

My class has 2 properties (String) that are two types of people's document numbers. To verify if the documents has valid numbers, a calculation is realized (verifiers digits). Below an example how is realized a consistensy of one of them:

Number: 973.345.650-02 (The punctuations must be ignored)

enter image description here

FIRST VERIFIER DIGIT CALCULATION

9 * 10 = 90
7 * 9 = 63
3 * 8 = 24
3 * 7 = 21
4 * 6 = 24
5 * 5 = 25
6 * 4 = 24
5 * 3 = 15
0 * 2 = 0
----------
Sum = 286

286 % 11 = 0

If rest < 2 then first digit = 0 
Or if rest >= 2 then first digit = 11 - rest

In this case, rest < 2 (0), then first verifier digit = 0

SECOND VERIFIER DIGIT CALCULATION

9 * 11 = 99
7 * 10 = 70
3 * 9 = 27
3 * 8 = 24
4 * 7 = 28
5 * 6 = 30
6 * 5 = 30
5 * 4 = 20
0 * 3 = 0
0 * 2 = 0    ==> FIRST VERIFIER DIGIT
----------
Sum = 328

328 % 11 = 9

Same rule of first verifier digit

If rest < 2 then first digit = 0 
Or if rest >= 2 then first digit = 11 - rest

The rest is greater than 2 (9), then second verifiter digit = 11 - 9 ==> 2

JAVA METHOD

public static boolean isValidCPF(String cpf) {
    
    cpf = cpf.replaceAll("[./-]", "");      

    if (cpf.length() < 11) {
        return false;
    }
            
    int equalDigits = 0;
    char compareChar = cpf.charAt(0);
    
    for (int i = 1; i <= 9; i++) {
        if (compareChar == cpf.charAt(i)) {
            equalDigits++;
        } else {
            break;
        }
    }
    
    if (equalDigits == 9) {
        return false;
    }
                    
    int[] digit = new int[2];
    int sum = 0, multiply = 2;
    
    for (int k = 8; k <= 9; k++) {
        
        for (int i = k; i >= 0; i--) {
            sum += Character.getNumericValue(cpf.charAt(i)) * multiply++ ;
        }
    
        digit[k-8] = (sum % 11) < 2 ? 0 : 11 - (sum % 11);
        sum = 0;
        multiply = 2;
        
    }
            
    if (cpf.equals(cpf.substring(0 , 9) + digit[0] + digit[1])) {
        return true;
    }
            
    return false;
}

I guess that OCL "sequence" must be used in this case (loop through digits) converting each one to Integer for calculation and using "body" in constraint, but I don't know how.

I want to apply the contraint to UML model in Papyrus (that's I know how to do).

Thanks in advance.

1 Answers1

1

You must think declaratively in aggregates so to emulate

   for (int i = 1; i <= 9; i++) {
    if (compareChar == cpf.charAt(i)) {
        equalDigits++;
    } else {
        break;
    }
}

you might try something like

Sequence{2..10}->select(i | cpf->at(i) = compareChar)->size()

NB OCL indexes start at 1.

Ed Willink
  • 1,205
  • 7
  • 8
  • Hi Ed. Thanks for the reply. Sorry for the incomplete explanation... This part of my code you put above checks that the first nine digits (the ones that are used for calculating the check digits) are used to check that they are all the same: 000000000, 111111111, etc. If they are all the same, then the document number is considered invalid. The two-digit part of the calculation comprises the "for" loop with another internal "for" further down the code. But I understand what you put. Thank you so much. – Adalberto José Brasaca Sep 15 '21 at 11:58