示例#1
0
def bindump( data, n = 8 ):
    """
        Return the first and last `n/2` bytes of a binary data, in hexadecimal format.
        
        :param data: Data to strip
        :rype data: str or list
        
        :return: Stripped hex representation
        :rtype: str
        
        Usage:
        
            >>> from NIST.core.functions import bindump
            >>> data = "".join( [ chr( x ) for x in xrange( 256 ) ] )
            >>> bindump( data )
            '00010203 ... FCFDFEFF (256 bytes)'
            
            >>> bindump( data, 16 )
            '0001020304050607 ... F8F9FAFBFCFDFEFF (256 bytes)'
    """
    pre = [ data[ i ] for i in xrange( n / 2 ) ]
    post = [ data[ -( i + 1 ) ] for i in xrange( n / 2 ) ]
    
    pre = multimap( [ ord, hexformat ], pre )
    post = multimap( [ ord, hexformat ], post )
    
    post = reversed( post )
    
    return "%s ... %s (%d bytes)" % ( join( "", pre ), join( "", post ), len( data ) )
示例#2
0
def bindump( data, n = 8 ):
    """
        Return the first and last `n/2` bytes of a binary data, in hexadecimal format.
        
        :param data: Data to strip
        :rype data: str or list
        
        :return: Stripped hex representation
        :rtype: str
        
        Let `data` be a list of all hex values between `00` and `FF`:
            
            >>> data = "".join( [ chr( x ) for x in xrange( 256 ) ] )
        
        The truncated representation will be:
        
            >>> bindump( data )
            '00010203 ... FCFDFEFF (256 bytes)'
            
            >>> bindump( data, 16 )
            '0001020304050607 ... F8F9FAFBFCFDFEFF (256 bytes)'
    """
    pre = [ data[ i ] for i in xrange( n / 2 ) ]
    post = [ data[ -( i + 1 ) ] for i in xrange( n / 2 ) ]
    
    pre = multimap( [ ord, hexformat ], pre )
    post = multimap( [ ord, hexformat ], post )
    
    post = reversed( post )
    
    return "%s ... %s (%d bytes)" % ( join( "", pre ), join( "", post ), len( data ) )
示例#3
0
    def to_json(self, return_bin=True, **options):
        """
            Export the content of the NIST object to JSON.
            
            :param return_bin: Include binary data in the JSON string. 
            :type return_bin: boolean
            
            :param options: Options to pass to the :func:`json.dumps()` function.
            :type options: kwargs
            
            :return: JSON string.
            :rtype: str
            
            .. note:: If the binary data is included in the JSON string, the data will be exported as hexadecimal representation.
            
        """
        self.clean()
        databis = defDict()
        for ntype, idc, tagid in self.get_all_tagid():
            value = self.get_field((ntype, tagid), idc)

            if self.is_binary(ntype, tagid):
                if return_bin:
                    databis[ntype][idc][tagid] = join(
                        multimap([ord, myhex], value))

            else:
                databis[ntype][idc][tagid] = value

        databis = databis.to_dict()

        return json.dumps(databis, **options)
示例#4
0
 def dumpbin( self ):
     """
         Return a binary dump of the NIST object. Writable in a file ("wb" mode).
         
         :return: Binary representation of the NIST object.
         :rtype: str
     """
     debug.info( "Dumping NIST in binary" )
     
     self.clean()
     self.patch_to_standard()
     
     outnist = []
     
     for ntype in self.get_ntype():
         for idc in self.get_idc( ntype ):
             if ntype == 4:
                 outnist.append( int_to_binstring( int( self.data[ ntype ][ idc ][ 1 ] ), 4 * 8 ) )
                 outnist.append( int_to_binstring( int( self.data[ ntype ][ idc ][ 2 ] ), 1 * 8 ) )
                 outnist.append( int_to_binstring( int( self.data[ ntype ][ idc ][ 3 ] ), 1 * 8 ) )
                 outnist.append( int_to_binstring( int( self.data[ ntype ][ idc ][ 4 ] ), 1 * 8 ) )
                 outnist.append( ( chr( 0xFF ) * 5 ) )
                 outnist.append( int_to_binstring( int( self.data[ ntype ][ idc ][ 5 ] ), 1 * 8 ) )
                 outnist.append( int_to_binstring( int( self.data[ ntype ][ idc ][ 6 ] ), 2 * 8 ) )
                 outnist.append( int_to_binstring( int( self.data[ ntype ][ idc ][ 7 ] ), 2 * 8 ) )
                 outnist.append( int_to_binstring( int( self.data[ ntype ][ idc ][ 8 ] ), 1 * 8 ) )
                 outnist.append( self.data[ ntype ][ idc ][ 999 ] )
             else:
                 od = OrderedDict( sorted( self.data[ ntype ][ idc ].items() ) )
                 outnist.append( join( GS, [ tagger( ntype, tagid ) + value for tagid, value in od.iteritems() ] ) + FS )
     
     return "".join( outnist )
示例#5
0
    def clean(self):
        """
            Function to clean all unused fields in the self.data variable. This
            function should check the content of the NIST file only for fields
            described in the NIST standard. For all particular implementations
            and implementation specific fields, overload this function in a new
            class.
            
            Check done in this function:
            
                * Delete all empty records, IDC and fields
                * Recalculate the content of the field 1.003
                * Check the IDC field for every ntype (fields x.002)
                * Reset all lengths (fields x.001)
        """
        debug.info("Cleaning the NIST object")

        #     Delete all empty data.
        for ntype in self.get_ntype():
            for idc in self.data[ntype].keys():

                #    Fields
                for tagid in self.data[ntype][idc].keys():
                    value = self.get_field("%d.%03d" % (ntype, tagid), idc)
                    if value == "" or value == None:
                        debug.debug(
                            "Field %02d.%03d IDC %d deleted" %
                            (ntype, tagid, idc), 1)
                        del (self.data[ntype][idc][tagid])

                #    IDC
                if len(self.data[ntype][idc]) == 0:
                    debug.debug("%02d IDC %d deleted" % (ntype, idc), 1)
                    del (self.data[ntype][idc])

            #    ntype
            if len(self.data[ntype]) == 0:
                debug.debug("%02d deleted" % (ntype), 1)
                del (self.data[ntype])

        #    Recheck the content of the NIST object and udpate the 1.003 field
        content = []
        for ntype in self.get_ntype()[1:]:
            for idc in self.get_idc(ntype):
                debug.debug("Type-%02d, IDC %d present" % (ntype, idc), 1)
                content.append("%s%s%s" % (ntype, US, idc))

        content.insert(0, "%s%s%s" % (1, US, len(content)))
        self.set_field("1.003", join(RS, content))

        #    Check the IDC values for all records
        for ntype in self.get_ntype()[1:]:
            for idc in self.get_idc(ntype):
                debug.debug(
                    "Type-%02d, IDC %d: update the IDC field (%02d.%03d)" %
                    (ntype, idc, ntype, 2), 1)
                self.set_field((ntype, 2), idc, idc)
示例#6
0
    def dump_record(self, ntype, idc=0, fullname=False, maxwidth=None):
        """
            Dump a specific ntype - IDC record.
            
            :param ntype: ntype value.
            :type ntype: int
            
            :param idc: IDC value
            :type idc: int
            
            :param fullname: Get the full name of the field.
            :type fullname: boolean
            
            :return: Printable string.
            :rtype: str
            
            Usage:
            
                >>> dump = n.dump_record( 1, 0 )
                >>> print( dump ) # doctest: +ELLIPSIS, +NORMALIZE_WHITESPACE
                NIST Type-01
                    01.001 LEN: 00000136
                    01.002 VER: 0300
                    01.003 CNT: 1<US>1<RS>2<US>0
                    01.004 TOT: USA
                    01.005 DAT: ...
                    01.006 PRY: 1
                    01.007 DAI: FILE
                    01.008 ORI: UNIL
                    01.009 TCN: ...
                    01.011 NSR: 00.00
                    01.012 NTR: 00.00
        """
        d = self.data[ntype][idc]

        ret = []

        if ntype != 1:
            ret.append("NIST Type-%02d (IDC %d)" % (ntype, idc))
        else:
            ret.append("NIST Type-%02d" % ntype)

        for tagid, value in iter(sorted(d.iteritems())):
            lab = get_label(ntype, tagid, fullname)
            header = "%02d.%03d %s" % (ntype, tagid, lab)

            field = self.format_field(ntype, tagid, idc)
            if maxwidth != None:
                field = printableFieldSeparator(field)
                field = "\n                ".join(
                    textwrap.wrap(field, int(maxwidth)))

            debug.debug("%s: %s" % (header, field), 2)
            ret.append(leveler("%s: %s" % (header, field), 1))

        return printableFieldSeparator(join("\n", ret))
示例#7
0
def decode_fgp( code, only_first = False, separator = "/" ):
    """
        Decode the integer value storing the Finger Position to a readable list
        of positions codes. This function implements the standard for the
        fields 3.004, 4.004, 5.004 and 6.004.
        
        The storage of the data is done in a binary format. A total of 6 bytes
        is used to store the possible 6 potentiels fingers. Each byte encode
        one possible finger using the code described in the Table 12 of the
        standard (only using the numbes 0 to 14 for fingers). The non-used
        fields shall be set to 255.

        Example:
        
            14:     00001110 11111111 11111111 11111111 11111111 11111111 (16492674416639)
            0:      00000000 11111111 11111111 11111111 11111111 11111111 (1099511627775)
            14/7/8: 00001110 00000111 00001000 11111111 11111111 11111111 (15423378554879)
        
        Usage:
        
            >>> from NIST.core.functions import decode_fgp
            >>> decode_fgp( 16492674416639 )
            '14'
            >>> decode_fgp( 1099511627775 )
            '0'
            >>> decode_fgp( 15423378554879 )
            '14/7/8'
    """
    code = int( code )
    
    # Get the binary representation, padded to 6 bytes
    code = int_to_bin( code, 6 * 8 )
    
    # Split in chunks of 8 bites
    code = [ code[ i:i + 8 ] for i in xrange( 0, len( code ), 8 ) ]
    
    # Convert each chunk to decimal
    code = [ bin_to_int( c ) for c in code ]
    
    # Remove the right padding
    code = [ str( c ) for c in code if c != 255 ]
    
    if only_first:
        return code[ 0 ]
    
    else:
        return join( separator, code )
示例#8
0
    def from_json(self, data):
        """
            Load the data from a JSON file. If some binary filds are present in
            the JSON file, the data will be converted from hexadecimal format to
            binary.
            
            :param data: JSON file or JSON string to import.
            :type data: str
            
            :return: NIST object.
            :rtype: NIST object
            
            Usage:
            
                >>> from NIST import NIST
                >>> n = NIST()
                >>> n.from_json( "sample/mark-pairing-nobinary.json" )
                >>> n
                NIST object, Type-01, Type-02, Type-09, Type-13
        """
        if isinstance(data, str) and os.path.isfile(data):
            with open(data) as fp:
                data = json.load(fp)

        elif isinstance(data, str):
            data = json.loads(data)

        self.data = defDict()

        for ntype, idcs in data.iteritems():
            ntype = int(ntype)
            self.add_ntype(ntype)

            for idc, tagids in idcs.iteritems():
                idc = int(idc)
                self.add_idc(ntype, idc)

                for tagid, value in tagids.iteritems():
                    tagid = int(tagid)

                    if self.is_binary(ntype, tagid):
                        value = join(
                            multimap([hex_to_int, chr], split(value, 2)))

                    self.set_field((ntype, tagid), value, idc)
示例#9
0
    def dump(self, fullname=False, maxwidth=None):
        """
            Return a readable version of the NIST object. Printable on screen.
            
            :param fullname: Get the fullname of the fields.
            :type fullname: boolean
            
            :return: Printable representation of the NIST object.
            :rtype: str
            
            Usage:
            
                >>> dump = n.dump()
                >>> print( dump ) # doctest: +ELLIPSIS, +NORMALIZE_WHITESPACE
                Informations about the NIST object:
                    Obj ID:  Doctester NIST object
                    Records: Type-01, Type-02
                    Class:   NISTf
                <BLANKLINE>
                NIST Type-01
                    01.001 LEN: 00000136
                    01.002 VER: 0300
                    01.003 CNT: 1<US>1<RS>2<US>0
                    01.004 TOT: USA
                    01.005 DAT: ...
                    01.006 PRY: 1
                    01.007 DAI: FILE
                    01.008 ORI: UNIL
                    01.009 TCN: ...
                    01.011 NSR: 00.00
                    01.012 NTR: 00.00
                NIST Type-02 (IDC 0)
                    02.001 LEN: 00000038
                    02.002 IDC: 0
                    02.004    : ...
        """
        debug.info("Dumping NIST")

        self.clean()

        ret = [
            "Informations about the NIST object:",
        ]

        if self.fileuri != None:
            ret.append(leveler("File:    " + self.fileuri, 1))

        if self.get_identifier() != None:
            ret.append(leveler("Obj ID:  " + self.get_identifier(), 1))

        ret.extend([
            leveler(
                "Records: " +
                ", ".join(["Type-%02d" % x for x in self.get_ntype()]), 1),
            leveler("Class:   " + self.__class__.__name__, 1), ""
        ])

        for ntype in self.get_ntype():
            debug.debug("NIST Type-%02d" % ntype, 1)

            for idc in self.get_idc(ntype):
                ret.append(self.dump_record(ntype, idc, fullname, maxwidth))

        return join("\n", ret)