Skip to content

Commit

Permalink
feat: Support for 8 length bines on ISOUtil
Browse files Browse the repository at this point in the history
Configured with the environment property ${jpos.util.bin.length}, it
should be a comma separated list of bines.

For example, if there are two 8 length bines "4000000" and "2000000",
then this property should be:

 jpos.util.bin.length = 4000000,2000000

fixes jpos#475

Signed-off-by: Arturo Volpe <[email protected]>
  • Loading branch information
aVolpe committed Aug 17, 2022
1 parent be081d8 commit b49b673
Show file tree
Hide file tree
Showing 2 changed files with 69 additions and 1 deletion.
54 changes: 53 additions & 1 deletion jpos/src/main/java/org/jpos/iso/ISOUtil.java
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@

package org.jpos.iso;

import org.jpos.core.Environment;
import java.math.BigDecimal;
import java.nio.ByteBuffer;
import java.nio.charset.Charset;
Expand All @@ -26,13 +27,18 @@
import java.util.ArrayList;
import java.util.Arrays;
import java.util.BitSet;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Random;
import java.util.Set;
import java.util.StringJoiner;
import java.util.StringTokenizer;
import java.util.concurrent.atomic.AtomicReference;
import java.util.regex.Pattern;
import java.util.stream.Collectors;


/**
* various functions needed to pack/unpack ISO-8583 fields
*
Expand Down Expand Up @@ -87,6 +93,25 @@ public ISOUtil() {
public static final byte GS = 0x1E;
public static final byte ETX = 0x03;

/**
* BIN configuration, used to support 8 length bines
*
* Configured with the enviornment property ${jpos.util.bin.length}, it
* should be a comma separated list of bines.
*
* For example, if there are two 8 length bines "4000000" and "2000000",
* then this property should be:
*
* <code>
* jpos.util.bin.length = 4000000,2000000
* </code>
*
* @see {@link org.jpos.core.Environment}
* @see #cleanBinCache()
* @see #protect(String, char)
**/
private static final AtomicReference<Set<String>> BIN_CONFIG = new AtomicReference<>();

public static String ebcdicToAscii(byte[] e) {
return EBCDIC.decode(ByteBuffer.wrap(e)).toString();
}
Expand Down Expand Up @@ -887,6 +912,26 @@ private static boolean isInternalUnicodeSequence(String s) {
public static String normalize (String s) {
return normalize(s, true);
}
private static Set<String> initBinConfig() {
String config = Environment.get("${jpos.util.bin.length}", "");
if (config == null || config.isEmpty()) {
BIN_CONFIG.set(Collections.emptySet());
}
String[] binArray = config.split(",");
Set<String> bines = new HashSet<String>();
Collections.addAll(bines, binArray);
BIN_CONFIG.set(bines);
return bines;
}
/**
* Clean the bin cache, see {@link #BIN_CONFIG}
*
* Call this method after changing the {@link Environment} so future calls to
* {@link #protect(String)} will re-calculate the bin list
**/
public static void cleanBinCache() {
BIN_CONFIG.set(null);
}
/**
* Protects PAN, Track2, CVC (suitable for logs).
*
Expand All @@ -903,7 +948,14 @@ public static String normalize (String s) {
public static String protect (String s, char mask) {
StringBuilder sb = new StringBuilder();
int len = s.length();
int clear = len > 6 ? 6 : 0;
Set<String> bines = BIN_CONFIG.get();

if (bines == null) bines = initBinConfig();

int binLength = 6;
if (len >= 8 && bines.contains(s.substring(0, 8))) binLength = 8;

int clear = len > binLength ? binLength : 0;
int lastFourIndex = -1;
if (clear > 0) {
lastFourIndex = s.indexOf ('=') - 4;
Expand Down
16 changes: 16 additions & 0 deletions jpos/src/test/java/org/jpos/iso/ISOUtilTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -45,11 +45,18 @@
import java.util.TimeZone;

import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Test;

public class ISOUtilTest {
final String lineSep = System.getProperty("line.separator");

@BeforeAll
static void cleanCache() {
ISOUtil.cleanBinCache();
System.setProperty("jpos.util.bin.length", "40000100");
}

@Test
public void testAsciiToEbcdic() throws Throwable {
byte[] a = new byte[0];
Expand Down Expand Up @@ -4386,6 +4393,15 @@ public void testProtectThrowsNullPointerException() throws Throwable {
});
}

@Test
void testProtectWithBin8() throws Exception {
ISOUtil.cleanBinCache();
System.setProperty("jpos.util.bin.length", "40000100");

assertEquals("410001______0101", ISOUtil.protect("4100010000000101", '_'), "Should mask a PAN with a bin of 6 digits");
assertEquals("40000100____0101", ISOUtil.protect("4000010000000101", '_'), "Should mask a PAN with a bin of 8 digits");
}

@Test
public void testSleep() throws Throwable {
ISOUtil.sleep(100L);
Expand Down

0 comments on commit b49b673

Please sign in to comment.