예제 #1
0
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))
예제 #2
0
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)
예제 #3
0
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)
예제 #4
0
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))
예제 #5
0
    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))
예제 #6
0
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
예제 #7
0
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)
예제 #8
0
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]))
예제 #9
0
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)