Skip to content

Commit

Permalink
Merge pull request #34 from realrolfje/feature/transient-synonyms
Browse files Browse the repository at this point in the history
Feature/transient synonyms
  • Loading branch information
realrolfje authored Jun 22, 2018
2 parents eb57822 + bbde08a commit 649bd4f
Show file tree
Hide file tree
Showing 46 changed files with 972 additions and 718 deletions.
3 changes: 3 additions & 0 deletions create_release.sh
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,9 @@ git commit -m "Update version to $2"

git push --follow-tags

# Sign the zip file
gpg -ab --default-key D6584B937338F123 target/anonimatron*.zip

echo "The file to upload for this release is:"
echo
ls -l target/anonimatron*.zip
Expand Down
2 changes: 1 addition & 1 deletion pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

<groupId>com.rolfje.anonimatron</groupId>
<artifactId>anonimatron</artifactId>
<version>1.9.4-SNAPSHOT</version>
<version>1.10.0-SNAPSHOT</version>
<packaging>jar</packaging>

<name>anonimatron</name>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -407,17 +407,13 @@ && hatesPreviousVocals(sur.get(c)) || last == 2
}

@Override
public Synonym anonymize(Object from, int size) {

StringSynonym synonym = new StringSynonym();
synonym.setFrom(from);

if (from != null){
synonym.setTo(getName(size));
}

synonym.setType(getType());
return synonym;
public Synonym anonymize(Object from, int size, boolean shortlived) {
return new StringSynonym(
getType(),
(String) from,
from == null ? null : getName(size),
shortlived
);
}

private String getName(int size) {
Expand Down
44 changes: 22 additions & 22 deletions src/main/java/com/rolfje/anonimatron/anonymizer/Anonymizer.java
Original file line number Diff line number Diff line change
Expand Up @@ -6,37 +6,37 @@

/**
* Provides functionality for consitently anonymizing a piece of data.
*
* <p>
* Implementations of this interface must make sure that anonymization is done
* in a reproducable manner. That is, if A transforms into B, it has to
* consistently do so on each and every call.
*
* <p>
* By doing this, anonimatron can guarantee that data is transformed
* consistently accross all tables of the database, and referential constraints
* can be re-enforced after anonymization.
*/
public interface Anonymizer {

/**
*
* @return The ID or name of this anonymizer, as used in the XML
* configuration file. This is generally something along the lines
* of "LASTNAME" or "UNEVENNUMBER". Please see the output of the
* -configexample command line option when running Anonimatron.
*/
String getType();
/**
* @return The ID or name of this anonymizer, as used in the XML
* configuration file. This is generally something along the lines
* of "LASTNAME" or "UNEVENNUMBER". Please see the output of the
* -configexample command line option when running Anonimatron.
*/
String getType();

/**
* Anonymizes the given data into a non-tracable, non-reversible synonym,
* and does it consistently, so that A always translates to B.
*
* @param from
* the data to be anonymized, usually passed in as a
* {@link String}, {@link Integer}, {@link Date} or other classes
* which can be stored in a single JDBC database column.
* @param size the optional maximum size of the generated value
* @return a {@link Synonym}
*/
Synonym anonymize(Object from, int size);
/**
* Anonymizes the given data into a non-tracable, non-reversible synonym,
* and does it consistently, so that A always translates to B.
*
* @param from the data to be anonymized, usually passed in as a
* {@link String}, {@link Integer}, {@link Date} or other classes
* which can be stored in a single JDBC database column.
* @param size the optional maximum size of the generated value
* @param shortlived indicates that the generated synonym must have the
* {@link Synonym#isShortLived()} boolean set
* @return a {@link Synonym}
*/
Synonym anonymize(Object from, int size, boolean shortlived);

}
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package com.rolfje.anonimatron.anonymizer;

import com.rolfje.anonimatron.configuration.Column;
import com.rolfje.anonimatron.synonyms.NullSynonym;
import com.rolfje.anonimatron.synonyms.Synonym;
import org.apache.log4j.Logger;
Expand Down Expand Up @@ -78,24 +79,32 @@ public Set<String> getDefaultAnonymizerTypes() {
return Collections.unmodifiableSet(defaultTypeMapping.keySet());
}

public Synonym anonymize(String type, Object from, int size) {
public Synonym anonymize(Column column, Object from) {
if (from == null) {
return new NullSynonym(type);
return new NullSynonym(column.getType());
}

// Hash from here.
String hashedFrom = new Hasher("secretsalt").base64Hash(from);

// Find for regular type
Synonym synonym = synonymCache.get(type, from);
Synonym synonym = getSynonym(column, from);

if (synonym == null) {
// Fallback for default type
synonym = synonymCache.get(defaultTypeMapping.get(type), from);
Anonymizer anonymizer = getAnonymizer(column.getType());
synonym = anonymizer.anonymize(from, column.getSize(), column.isShortLived());

synonymCache.put(synonym);
}
return synonym;
}

private Synonym getSynonym(Column c, Object from) {
if (c.isShortLived()){
return null;
}

Synonym synonym = synonymCache.get(c.getType(), from);
if (synonym == null) {
synonym = getAnonymizer(type).anonymize(from, size);
synonymCache.put(synonym);
// Fallback for default type
synonym = synonymCache.get(defaultTypeMapping.get(c.getType()), from);
}
return synonym;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,29 +17,30 @@ protected String getDefaultCharacterString() {
return "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
}



@Override
public String getType() {
return "RANDOMCHARACTERS";
}

@Override
public Synonym anonymize(Object from, int size) {
int length = from.toString().length();
public Synonym anonymize(Object from, int size, boolean shortlived) {
String fromString = from.toString();
Random r = new Random();

int length = fromString.length();
StringBuilder sb = new StringBuilder();
for (int i = 0; i < length; i++) {
sb.append(CHARS.charAt(r.nextInt(CHARS.length())));
}

String to = sb.toString();

StringSynonym stringSynonym = new StringSynonym();
stringSynonym.setFrom(from);
stringSynonym.setType(getType());
stringSynonym.setTo(to);
StringSynonym stringSynonym = new StringSynonym(
getType(),
fromString,
to,
shortlived
);

return stringSynonym;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,12 +32,12 @@ public void prefetch(Object sourceData) {
}

@Override
public Synonym anonymize(Object from, int size) {
public Synonym anonymize(Object from, int size, boolean shortlived) {
if (CHARS.length() < 1) {
LOG.warn("No characters were collected during prefetch. Using the default set '" + getDefaultCharacterString() + "'.");
CHARS = getDefaultCharacterString();
}
return super.anonymize(from, size);
return super.anonymize(from, size, shortlived);
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ public String getType() {
}

@Override
public Synonym anonymize(Object from, int size) {
public Synonym anonymize(Object from, int size, boolean shortlived) {

if (size < 2) {
throw new UnsupportedOperationException("Can not produce country codes of one character.");
Expand All @@ -50,10 +50,9 @@ else if (size == 2) {
return new StringSynonym(
getType(),
from.toString(),
country
country,
shortlived
);


}

public static String padRight(String s, int n) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,10 @@ class DateAnonymizer implements Anonymizer {
private Set<Date> generatedDates = new HashSet<Date>();

@Override
public Synonym anonymize(Object from, int size) {
public Synonym anonymize(Object from, int size, boolean shortlived) {
DateSynonym s = new DateSynonym();
s.setType(TYPE);
s.setShortlived(shortlived);

if (from == null) {
s.setFrom(null);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,16 +11,18 @@ public String getType() {
}

@Override
public Synonym anonymize(Object from, int size) {
public Synonym anonymize(Object from, int size, boolean shortlived) {
int length = from.toString().length();

int[] digits = getRandomDigits(length);
String to = digitsAsNumber(digits);

StringSynonym stringSynonym = new StringSynonym();
stringSynonym.setFrom(from);
stringSynonym.setType(getType());
stringSynonym.setTo(to);
StringSynonym stringSynonym = new StringSynonym(
getType(),
(String) from,
to,
shortlived
);

return stringSynonym;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,47 +13,52 @@
* See http://nl.wikipedia.org/wiki/Rekeningnummer
*/
public class DutchBSNAnononymizer extends AbstractElevenProofAnonymizer {
private static int LENGTH = 9;

@Override
public String getType() {
return "BURGERSERVICENUMMER";
}

@Override
public Synonym anonymize(Object from, int size) {
if (size < LENGTH) {
throw new UnsupportedOperationException(
"Can not generate a BSN that fits in a "
+ size
+ " character string. Must be " + LENGTH + " characters or more.");
}

StringSynonym s = new StringSynonym();
s.setType(getType());
s.setFrom(from);

do {
// Never generate identical number
s.setTo(generateBSN(LENGTH));
} while (s.getFrom().equals(s.getTo()));

return s;
}

String generateBSN(int numberOfDigits) {
// Generate random BSN number
int[] bsnnumber;

do {
bsnnumber = generate11ProofNumber(numberOfDigits);

// SOFI numbers can not start with 3 zeroes, left digit digit van
// not be >3
} while ((bsnnumber[0] > 3) && (0 != (bsnnumber[0] + bsnnumber[1] + bsnnumber[2])));

// Return the BSN
String result = digitsAsNumber(bsnnumber);
return result;
}
private static int LENGTH = 9;

@Override
public String getType() {
return "BURGERSERVICENUMMER";
}

@Override
public Synonym anonymize(Object from, int size, boolean shortlived) {
if (size < LENGTH) {
throw new UnsupportedOperationException(
"Can not generate a BSN that fits in a "
+ size
+ " character string. Must be " + LENGTH + " characters or more.");
}

String fromString = (String) from;
String toString = fromString;

do {
// Never generate identical number
toString = generateBSN(LENGTH);
} while (fromString.equals(toString));


return new StringSynonym(
getType(),
fromString,
toString,
shortlived
);
}

String generateBSN(int numberOfDigits) {
// Generate random BSN number
int[] bsnnumber;

do {
bsnnumber = generate11ProofNumber(numberOfDigits);

// SOFI numbers can not start with 3 zeroes, left digit digit van
// not be >3
} while ((bsnnumber[0] > 3) && (0 != (bsnnumber[0] + bsnnumber[1] + bsnnumber[2])));

// Return the BSN
String result = digitsAsNumber(bsnnumber);
return result;
}
}
Loading

0 comments on commit 649bd4f

Please sign in to comment.