def region_anon(self): from .field_map import ten_digits_starting_w_1 from .alter import fixed_length_string self.region_name = anon_term(term=self.region_name, func=fixed_length_string(4)) self.dim_facility_pk = int(anon_term(term=self.dim_facility_pk, func=ten_digits_starting_w_1))
def test_cached_term(): "two calls return same altered result" random_f = fixed_length_string(25) input = "Bob. G Longbottom" first = anon_term(input, random_f) second = anon_term(input, random_f) assert(first != input) assert(first == second)
def test_cached_date(): "two calls return same altered date" random_f = random_date_delta(datetime.timedelta(days=5000)) input = datetime.datetime.now() first = anon_term(input, random_f) second = anon_term(input, random_f) assert(first != input) assert(isinstance(first, datetime.datetime)) assert(first == second)
def facility_anon(self): from .field_map import short_string, ten_digits_starting_w_1 from .field_map import five_digits, site_string from .alter import fixed_length_string self.county = anon_term(term=self.county, func=short_string) self.npi = int(anon_term(term=self.npi, func=ten_digits_starting_w_1)) self.zip = str(five_digits(self.zip)) # ignore cached!! self.organization_name = anon_term(term=self.organization_name, func=site_string) self.local_code = anon_term(term=self.local_code, func=fixed_length_string(3))
def anonymize(self): """apply the anonymize map to the instance message returns an anonymized version of the message. """ # preserve idempotence if hasattr(self, '_anonymized'): return str(unicode(self.msg)) # apply all anon methods applicable to this message for hl7segment in self.msg: segment = str(hl7segment[0][0]) # MSH, PID, OBX, etc. if segment in anon_map: for element in anon_map[segment].keys(): # i.e. EVN-2 for component in anon_map[segment][element].keys(): anon_method = anon_map[segment][element][component] # adjust hl7 one versus zero index try: cur_val = hl7segment[element][component - 1] except IndexError: # said component not in the hl7segment # safe to ignore and continue continue hl7segment[element][component - 1] =\ anon_term(term=cur_val, func=anon_method) self._anonymized = True return str(unicode(self.msg))
def msg_control_id(initial): """specialized anon function for message control id message control id is a long integer made up from concatination of: - source identifier - timestamp (YYYYMMDDhhmmss) - counter [0000-9999] attempt to be consistent with the source identifier and use same shift for timestamp """ counter = initial[-4:] timestamp = initial[-18:-4] source_id = initial[:-18] return anon_term(source_id, ten_digits) +\ anon_term(timestamp, ymdhms) + counter
def ten_digits_starting_w_1(initial): """specialized anon function for NPI like numbers 10 digits in length, starting w/ 1 to prevent integer overflow at 2,147,483,647 """ def one_and_nine(initial): return '1' + nine_digits(initial) return anon_term(initial, one_and_nine)
def facility_subcomponents(initial): """specialized anon function for PID-3.4 and 3.6 Some facility components make use of sub-component separator '&'. Handle here as a shortcut to extending the depth of the anon engine. Take care to check the cache for the first two sub-components as they are also stand alone components (i.e. MSH-4.1, MSH-4.2) and we'd like to substitute in the same values. """ if initial is None or len(initial) == 0: return initial parts = initial.split('&') if len(parts) < 3: return anon_term(initial, dotted_sequence) return '&'.join((anon_term(parts[0], site_string), anon_term(parts[1], dotted_sequence), parts[2]))
def type_and_magnitude(initial): """return string matching type and magnitude If initial looks like an integer, return string form of integer of same magnitude. Same idea for floating point values. Otherwise return a random short_string. """ if initial is None or len(initial) == 0: return initial try: value = int(initial) return anon_term(initial, fixed_length_digits(len(initial))) except ValueError: try: value = float(initial) lenb4 = initial.find('.') return anon_term(initial, fixed_length_digits(len(initial), (lenb4, lenb4+1))) except ValueError: return short_string(initial)