jpos / jPOS

jPOS Project
http://jpos.org
GNU Affero General Public License v3.0
609 stars 461 forks source link

Protect name in Track1 of the ISOUtil.protect #579

Open mchhil-incomm opened 9 months ago

mchhil-incomm commented 9 months ago
System.out.println(ISOUtil.protect("B4000340000000504^John/Doe                  ^22251110000123000"));

Output

B40003_______0504^John/Doe                  ^_________________

John/Doe is not protected.

Change

https://github.com/jpos/jPOS/blob/master/jpos/src/main/java/org/jpos/iso/ISOUtil.java#L929-L938

        try {
           //Addresses Track1 Truncation
           int charCount = s.replaceAll("[^\\^]", "").length();
           if (charCount == 2 ) {
               s = s.substring(0, s.lastIndexOf("^")+1);
               s = ISOUtil.padright(s, len, mask);
           }
       } catch (ISOException e){
           //cannot PAD - should never get here
       }

to

//https://en.wikipedia.org/wiki/ISO/IEC_7813
/*

SS : Start sentinel "%"
FC : Format code "B" (The format described here. Format "A" is reserved for proprietary use.)
PAN : Payment card number 4400664987366029, up to 19 digits
FS : Field separator "^"
NM : Name, 2 to 26 characters (including separators, where appropriate, between surname, first name etc.)
FS : Field separator "^"
ED : Expiration data, 4 digits or "^"
SC : Service code, 3 digits or "^"
DD : Discretionary data, balance of characters
ES : End sentinel "?"
LRC : Longitudinal redundancy check, calculated according to ISO/IEC 7811-2
*/

try {
//Addresses Track1 Truncation
int charCount = s.replaceAll("[^\\^]", "").length();
if (charCount >= 2) {
int firstCaret = s.indexOf("^");
int secondCaret = s.indexOf("^", firstCaret + 1);

s = s.substring(0, firstCaret + 1);
s = ISOUtil.padright(s, secondCaret, mask);
s = s.concat("^");
s = ISOUtil.padright(s, len, mask);
}
} catch (ISOException e){
//cannot PAD - should never get here
}

Output

B40003_______0504^__________________________^_________________
ar commented 8 months ago

@mchhil-incomm at your convenience, please check f66f287 sent against next. If you think it solves the issue, we can back port it to master. I also took the opportunity to remove a few tests that would break with this change, but made no sense.

mchhil-incomm commented 8 months ago

@ar  your protect0 is what I have implemented and is being used by other projects here internally. As for the protect method, I believe your test case covers it.

Should there be a test case to make sure results of protect0 and protect yield identical results?

ar commented 8 months ago

Oh... protect0 was just placed as a reference while coding the protect :) — I'll take it away.

mchhil-incomm commented 8 months ago

@ar The test case does not look right. For clarity you can try "=====^apr/apr^====^==="

   @Test
    public void testProtect10() throws Throwable {
        String result = ISOUtil.protect("=====^===========^====^===");
        assertEquals("=====^===========^====^===", result, "result");
    }

The name is not masked in it, unless its a special kind of track data that I am not aware of. The data after the first ^ has not changed because the following check

        if (firstSeparatorIndex < 6) {
            return s; // nothing to do
        }

The old method would have returned 

=====^___________^________

for an input of "=====^===========^====^==="

For regression, it would be good to test the old output equals the new one.

ar commented 8 months ago

@mchhil-incomm the track1 "=====^apr/apr^====^===" looks invalid to me to start with. That would be a six digits card number, which looks invalid.

For regression, it would be good to test the old output equals the new one. I think some of the old tests were just wrong, hence adjusted.