def _parse_data(self): self.TransactionType = util.en1545_EventTypeCode(util.byterange(self.data, 2, 0.5).uint) self.TransactionSequenceNumber = util.byterange(self.data, 2.5, 1.5).uint self.DateTimeStamp = util.en1545_DATETIME_from(util.byterange(self.data, 4, 3).uint) self.ISAMIDModifier = util.byterange(self.data, 7, 4).hex self.ActionSequenceNumber = util.byterange(self.data, 11, 1).uint self.CountRemainingRidesJourney = util.byterange(self.data, 12, 1).uint self.CountTransfers = util.byterange(self.data, 13, 1).uint self.TYP23ValueFlags = util.byterange(self.data, 14, 1)
def _parse_directory(self): self.directory_bitmap = util.bitrange(self.directory_bits, (0, 1), (1, 4)) self._parse_directory_bitmap() directory_format_revision = util.bitrange(self.directory_bits, (1, 3), (1, 0)) # Sector Chain Table for x in range(0, self.shell.max_sectors - 3): position = (16 + 5 * 8 * self.shell.max_directory_entries) + self.shell.psi * x entry_bits = self.directory_bits[position:position + self.shell.psi].uint self.sct[x + 1] = entry_bits # Directory Entries for x in range(1, self.shell.max_directory_entries): position = 16 + 5 * 8 * x entry_bits = self.directory_bits[position:position + 40] # Skip entry empties if entry_bits.uint == 0: continue entry = IPEDirectoryEntry(x, entry_bits, self.sct, self.shell.max_sectors) self.entries.append(entry) # Cyclic Log log_location = (16 + 5 * 8 * self.shell.max_directory_entries) log = self.directory_bits[log_location:log_location + 40] self.log = LogDirectoryEntry(log, self.sct, self.shell.max_sectors) sequence_location = (16 + 5 * 8 * self.shell.max_directory_entries ) + self.shell.sctl_size * 8 self.sequence = self.directory_bits[ sequence_location:sequence_location + 8].uint self.kid = self.directory_bits[sequence_location + 8:sequence_location + 12] self.shell_iteration = self.directory_bits[sequence_location + 12:sequence_location + 16].uint self.isamid = self.directory_bits[sequence_location + 16:sequence_location + 48]
def _parse_entry(self): self.normal = self.entry[0] self.pointer = self.entry[1:6].uint self.direction = self.entry[6:7].uint self.timestamp = util.en1545_DATE_from(self.entry[8:16].uint) self.offset = self.entry[32:33] self.passback = self.entry[33:39].uint
def _parse_value(self): for x in range(1, len(self.ipe.files)): file = self.ipe.files[x] VGBitmap = util.byterange(file, 0.75, 0.75) for y in range(0, VGBitmap[:-1].count(1)): record_start = 16 + 120*y record_end = record_start + 120 record = self.ipe.files[x][:16] + self.ipe.files[x][record_start:record_end] value = JourneyValue(record) self.values.append(value)
def _parse_data(self): self.RemoveDate = util.byterange(self.ipe.data, 2, 1).uint self.ProductRetailer = util.byterange(self.ipe.data, 3, 2).hex self.TYP23Flags = util.byterange(self.ipe.data, 5, 1).hex self.PassbackTime = util.byterange(self.ipe.data, 6.25, 0.75).uint self.IssueDate = util.en1545_DATE_from(util.byterange(self.ipe.data, 7.25, 1.75).uint) self.ValidityCode = util.byterange(self.ipe.data, 9, 0.625).uint self.ExpiryTime = util.byterange(self.ipe.data, 9.625, 1.375).uint self.Class = util.byterange(self.ipe.data, 11.625, 0.375).uint self.PartySizeAdult = util.byterange(self.ipe.data, 12, 1).uint self.PartySizeChild = util.byterange(self.ipe.data, 13, 1).uint self.PartySizeConcession = util.byterange(self.ipe.data, 14, 1).uint self.AmountPaidCurrencyCode = util.byterange(self.ipe.data, 15.5, 0.5).uint if self.ipe.format_revision == 1: self.AmountPaid = util.byterange(self.ipe.data, 16, 2).uint self.AmountPaidMethodOfPayment = util.byterange(self.ipe.data, 18, 0.5).uint self.AmountPaidVATSalesTax = util.byterange(self.ipe.data, 18.5, 1.5).uint self.PhotocardNumber = util.byterange(self.ipe.data, 20, 4) self.PromotionCode = util.byterange(self.ipe.data, 24, 1) self.ConcessionaryPassIssuerCostCentre = util.byterange(self.ipe.data, 25, 2) self.TYP23Mode = util.byterange(self.ipe.data, 27.5, 0.5) self.MaxTransfers = util.byterange(self.ipe.data, 28, 1).uint self.TimeLimit = util.byterange(self.ipe.data, 29, 1).uint self.ValueOfRideJourney = util.byterange(self.ipe.data, 30, 2).uint self.ValueOfRideJourneyCurrency = util.byterange(self.ipe.data, 32.5, 0.5) self.Origin1 = util.byterange(self.ipe.data, 33, 17) self.Destination1 = util.byterange(self.ipe.data, 50, 17) self.IIN = util.byterange(self.ipe.data, 67, 3) elif self.ipe.format_revision == 2: self.AmountPaid = util.byterange(self.ipe.data, 16, 2).uint self.AmountPaidMethodOfPayment = util.byterange(self.ipe.data, 18, 0.5).uint self.AmountPaidVATSalesTax = util.byterange(self.ipe.data, 18.5, 1.5).uint self.PhotocardNumber = util.byterange(self.ipe.data, 20, 4) self.PromotionCode = util.byterange(self.ipe.data, 24, 1) self.ConcessionaryPassIssuerCostCentre = util.byterange(self.ipe.data, 25, 2) self.TYP23Mode = util.byterange(self.ipe.data, 29.5, 0.5) self.MaxTransfers = util.byterange(self.ipe.data, 30, 1).uint self.TimeLimit = util.byterange(self.ipe.data, 31, 1).uint self.ValueOfRideJourney = util.byterange(self.ipe.data, 32, 2).uint self.ValueOfRideJourneyCurrency = util.byterange(self.ipe.data, 34.5, 0.5) self.RouteCode = util.byterange(self.ipe.data, 34.5, 0.5) self.Origin1 = util.byterange(self.ipe.data, 40, 17) self.Destination1 = util.byterange(self.ipe.data, 57, 17) self.IIN = util.byterange(self.ipe.data, 74, 3)
def _parse_shell(self): self.shell_length = util.bitrange(self.shell_bits, (0, 7), (0, 2)).uint self.shell_bitmap = util.bitrange(self.shell_bits, (0, 1), (1, 4)) self._parse_shell_bitmap() shell_format_revision = util.bitrange(self.shell_bits, (1, 3), (1, 0)).hex # Compact shells only contain four basic fields. if self.shell_bitmap_type == self.TYPES.COMPACT: FVC = util.bitrange(self.shell_bits, (2, 0), (2, 7)).hex return isrn_iin = util.bitrange(self.shell_bits, (2, 7), (4, 0)) isrn_oid = util.bitrange(self.shell_bits, (5, 7), (6, 0)) isrn_issn = util.bitrange(self.shell_bits, (7, 7), (10, 4)) isrn_chd = util.bitrange(self.shell_bits, (10, 3), (10, 0)) isrn = isrn_iin + isrn_oid + isrn_issn + isrn_chd self.isrn = util.bcd_digits(isrn.bytes) self.FVC = util.bitrange(self.shell_bits, (11, 7), (11, 0)).uint self.KSC = util.bitrange(self.shell_bits, (12, 7), (12, 0)).uint self.KVC = util.bitrange(self.shell_bits, (13, 7), (13, 0)).uint expiry_bitrange = util.bitrange(self.shell_bits, (14, 5), (15, 0)) self.expiry = util.en1545_DATE_from(expiry_bitrange.uint) self.sector_size = util.bitrange(self.shell_bits, (16, 7), (16, 0)).uint self.max_sectors = util.bitrange(self.shell_bits, (17, 7), (17, 0)).uint self.psi = len('{0:b}'.format(self.max_sectors - 1)) self.max_directory_entries = util.bitrange(self.shell_bits, (18, 7), (18, 0)).uint self.sctl_size = util.bitrange(self.shell_bits, (19, 7), (19, 0)).uint if not self.shell_bitmap_mcrn: SECRC = util.bitrange(self.shell_bits, (22, 7), (23, 0)) else: # The Multi-application CM reference is padded with 0x and ends # in a check digit. These aren't part of the reference number, so # let's remove them. mcrn = util.bitrange(self.shell_bits, (20, 7), (29, 0)) mcrn.replace('0xf', '') self.mcrn = mcrn.hex[:-1] SECRC = util.bitrange(self.shell_bits, (30, 7), (31, 0))
def _parse_data(self): self.RemoveDate = util.byterange(self.ipe.data, 2, 1).uint self.ConcessionaryPassIssuerCostCentre = util.byterange( self.ipe.data, 3, 2).hex self.IDFlags = util.byterange(self.ipe.data, 5, 1).hex self.RoundingFlagsEnable = util.byterange(self.ipe.data, 6, 0.125).bin self.PassbackTime = util.byterange(self.ipe.data, 6.25, 0.75).uint self.DateOfBirth = util.byterange(self.ipe.data, 7, 4, True) self.Language = util.byterange(self.ipe.data, 11, 1).uint self.HolderID = util.byterange(self.ipe.data, 11.625, 0.375).uint self.RoundingFlag = util.byterange(self.ipe.data, 16, 0.125).bin self.RoundingValueFlag = util.byterange(self.ipe.data, 16.13, 0.125).bin self.EntitlementExpiryDate = util.en1545_DATE_from( util.byterange(self.ipe.data, 16.25, 1.75).uint) self.DepositMethodOfPayment = util.byterange(self.ipe.data, 18, 0.5).uint self.DepositVATSalesTax = util.byterange(self.ipe.data, 18.5, 1.5).uint self.ShellDepositMethodOfPayment = util.byterange( self.ipe.data, 20, 0.5).uint self.ShellDepositVATSalesTax = util.byterange(self.ipe.data, 20.5, 1.5).uint self.DepositCurrencyCode = util.byterange(self.ipe.data, 22, 0.5).uint self.ShellDepositCurrencyCode = util.byterange(self.ipe.data, 22.5, 0.5).uint self.DepositAmount = util.byterange(self.ipe.data, 23, 2).uint self.ShellDeposit = util.byterange(self.ipe.data, 25, 2).uint self.EntitlementCode = util.byterange(self.ipe.data, 27, 1).uint self.ConcessionaryClass = util.byterange(self.ipe.data, 28, 1).uint self.SecondaryHolderID = util.byterange(self.ipe.data, 29, 4).uint self.ForenameLength = util.byterange(self.ipe.data, 33, 1).uint self.Forename = util.byterange( self.ipe.data, 34, self.ForenameLength).bytes.decode("ascii") surname_position = 34 + self.ForenameLength self.SurnameLength = util.byterange(self.ipe.data, surname_position, 1).uint self.Surname = util.byterange(self.ipe.data, surname_position + 1, self.SurnameLength) ending_position = surname_position + self.SurnameLength self.HalfDayOfWeek = util.byterange(self.ipe.data, ending_position, 2) self.ValidAtOrFrom = util.byterange(self.ipe.data, ending_position + 2, 17) self.ValidTo = util.byterange(self.ipe.data, ending_position + 36, 17) self.IIN = util.byterange(self.ipe.data, ending_position + 53, 3)
def _parse_data(self): self.TransactionType = util.en1545_EventTypeCode( util.byterange(self.data, 2, 0.5).uint) self.TransactionSequenceNumber = util.byterange(self.data, 2.5, 1.5).uint self.DateTimeStamp = util.en1545_DATETIME_from( util.byterange(self.data, 4, 3).uint) self.ISAMIDModifier = util.byterange(self.data, 7, 4).hex self.ActionSequenceNumber = util.byterange(self.data, 11, 1).uint self.Value = util.byterange(self.data, 12, 2).uint self.ValueCurrencyCode = util.byterange(self.data, 14, 0.5) self.CountJourneyLegs = util.byterange(self.data, 14.5, 0.5) self.CumulativeFare = util.byterange(self.data, 15, 1.625).uint self.TYP2ValueFlags = util.byterange(self.data, 16.625, 0.375)
def _parse_data(self): self.RemoveDate = util.byterange(self.ipe.data, 2, 1).uint self.ProductRetailer = util.byterange(self.ipe.data, 3, 2).hex self.TYP2Flags = util.byterange(self.ipe.data, 5, 1).hex self.Threshold = util.byterange(self.ipe.data, 6, 2).uint self.MaxValue2 = util.byterange(self.ipe.data, 10, 2).uint self.MaximumNegativeAmount = util.byterange(self.ipe.data, 12, 2).uint self.DepositAmount = util.byterange(self.ipe.data, 14, 2).uint self.StartDateAutoTopUp = util.en1545_DATE_from( util.byterange(self.ipe.data, 16, 1.75).uint) self.DepositMethodOfPayment = util.byterange(self.ipe.data, 19.5, 0.5) self.DepositCurrencyCode = util.byterange(self.ipe.data, 20, 0.5) self.DepositVATSalesTax = util.byterange(self.ipe.data, 20.5, 2).uint