| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128 |
- #!/usr/bin/python
- #
- # Copyright (c) 2019 Clementine Computing LLC.
- #
- # This file is part of PopuFare.
- #
- # PopuFare is free software: you can redistribute it and/or modify
- # it under the terms of the GNU Affero General Public License as published by
- # the Free Software Foundation, either version 3 of the License, or
- # (at your option) any later version.
- #
- # PopuFare is distributed in the hope that it will be useful,
- # but WITHOUT ANY WARRANTY; without even the implied warranty of
- # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- # GNU Affero General Public License for more details.
- #
- # You should have received a copy of the GNU Affero General Public License
- # along with PopuFare. If not, see <https://www.gnu.org/licenses/>.
- #
- # The output format is `<bit-length>|<payload>`, where the
- # <bit-length> and <payload> field are in ascii hex.
- #
- # Input is expected to come from stdin and as the result of the
- # `proxmark3` LUA script setup for low frequency read.
- # Input text is seached for a matching prefix of:
- #
- # #db# TAG ID:
- #
- # Once found, the ascii hex string is read, it's converted to binary
- # and parsed.
- # The first run of two '1' bits is removed from the 'left'.
- # The remaing number of bits is the bit length and the remaining
- # bit string is converted back to ascii.
- # Note the 'paylaod' can be a non exact multiple of 4 or 2.
- #
- # For example, if the following string was found:
- #
- # #db# TAG ID: 200712054a (677)
- #
- # This is converted to:
- #
- # 2 0 0 7 1 2 0 5 4 a
- # 0010 0000 0000 01 11 0001 0010 0000 0101 0100 1010
- # | |
- # -----------------------------------
- # 26 bits
- #
- # To evenually give the final result:
- #
- # 23|43F6311B2
- #
- import os
- import re
- import sys
- import time
- import datetime
- RATE_LIMIT_MS = 1500.0
- def convert_tagid(s):
- binstr = ""
- for c in s:
- v = int(c, 16)
- _b = bin(int(c, 16))[2:]
- __b = "0"*(4-len(_b)) + _b
- binstr = binstr + __b
- f, s, = -1, -1
- for idx, b in enumerate(binstr):
- if (b == '1') and (f < 0):
- f = idx
- elif (b == '1') and (s < 0):
- s = idx
- break
- filt_binstr = binstr[s+1:]
- n = len(filt_binstr)
- bitlen = n
- fin_hex = ""
- while n >= 4:
- _b = filt_binstr[n-4:n]
- fin_hex = hex(int(_b, 2))[2:] + fin_hex
- n -= 4
- if n>0:
- _b = filt_binstr[0:n]
- fin_hex = hex(int(_b, 2))[2:] + fin_hex
- return hex(bitlen)[2:] + "|" + fin_hex
- t_prv = time.time()*1000.0
- t_now = t_prv
- LAST_TOK = ""
- while True:
- line = sys.stdin.readline()
- line = line.strip()
- m = re.match("#db# TAG ID: ([^ ]*)", line)
- if m:
- t_now = time.time()*1000.0
- tok = convert_tagid(m.group(1)).upper()
- if LAST_TOK != tok:
- #sys.stdout.write( str(datetime.datetime.now()) + ": " + str(tok) + "\n")
- sys.stdout.write( str(int(time.time())) + ": " + str(tok) + "\n")
- sys.stdout.flush()
- t_prv = t_now
- LAST_TOK = tok
- elif (t_now - t_prv) >= RATE_LIMIT_MS:
- #sys.stdout.write( str(datetime.datetime.now()) + ": " + str(tok) + "\n")
- sys.stdout.write( str(int(time.time())) + ": " + str(tok) + "\n")
- sys.stdout.flush()
- t_prv = t_now
- LAST_TOK = tok
- else:
- pass
|