class MasterKey(object): def __init__(self, master_key_hex_string="0x3cc849279ba298b587a34cabaeffc5ecb3a044bbf97c516fab7ede9d1af77cfa"): self.key = BitArray(master_key_hex_string) self.session_keys_amount = 8 self.current_cycle_index = 0 self.master_key_round_shift_bits = 24 def get_round_keys(self): """ :return: list of round keys :rtype: list[RoundKey] """ if self.current_cycle_index: round_master_key = self.key.copy() round_master_key.ror(self.master_key_round_shift_bits * self.current_cycle_index) else: round_master_key = self.key.copy() round_keys = [] round_key_size = round_master_key.length / self.session_keys_amount for key_index in range(0, self.session_keys_amount): round_key = round_master_key[key_index * round_key_size:key_index * round_key_size + round_key_size] round_keys.append(RoundKey(round_key)) if self.current_cycle_index < 8: self.current_cycle_index += 1 else: self.current_cycle_index = 0 return round_keys
def stop_packet(direction=1, soft_stop=False, ignore_direction=True): """ Build a stop packet for all decoders. param direction sets the direction bit in the packet. param soft_stop indicates if the decoder bring the locomotive to stop or stop delivering energy to the engine (guess in the first case it may gradually decelerate it) param ignore_direction allows optionally ignoring the direction bit for all direction sensitive functions """ byte_one = BitArray('0b00000000') byte_two = BitArray('0b01') if direction: byte_two.append('0b1') else: byte_two.append('0b0') if ignore_direction: byte_two.append('0b1') else: byte_two.append('0b0') byte_two.append('0b000') if soft_stop: byte_two.append('0b0') else: byte_two.append('0b1') byte_three = byte_two.copy() return DCCGeneralPacket(byte_one, [byte_two, byte_three])
def testCopyMethod(self): s = BitArray(9) t = s.copy() self.assertEqual(s, t) t[0] = True self.assertEqual(t.bin, '100000000') self.assertEqual(s.bin, '000000000')
def _walk_tree(node, current: BitArray = BitArray()) -> Dict[str, BitArray]: """ Walk the Huffman Tree, constructing a dictiary of their associated bit arrays """ if node.data is not None: return {node.data: current} else: left_array: BitArray = current.copy() left_array.append('0b0') right_array: BitArray = current.copy() right_array.append('0b1') result: Dict[str, BitArray] = {} result.update(HuffmanTree._walk_tree(node.left, left_array)) result.update(HuffmanTree._walk_tree(node.right, right_array)) return result
def test_bitstring_extraction(): secret_bytes = SECRET.encode() secret_bit = BitArray(bytes=secret_bytes, length=len(secret_bytes) * 8) print(secret_bit.bin) print("Length of bits original secret: %d" % len(secret_bit)) checksum_bit = BitArray(uint=binascii.crc32(secret_bit.bytes), length=CRC_LENGTH) print(checksum_bit.bin) print(len(checksum_bit)) # join secret bitstring with CRC total_bit = secret_bit.copy() total_bit.append(checksum_bit) print('Length total bit: {}'.format(len(total_bit))) coefficients = [] assert len(total_bit) % 13 == 0 step = int(len(total_bit) / 13) for i in range(0, len(total_bit), step): coefficients.append(total_bit[i:i + step].uint) print(coefficients) PolynomialExtractor.check_crc_in_poly(coefficients, POLY_DEGREE, CRC_LENGTH) poly = [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 83, 69, 67, 82, 69, 84, 46, 46, 46, 201, 112, 67, 73 ] print(PolynomialExtractor.check_crc_in_poly(poly, POLY_DEGREE, CRC_LENGTH))
def encrypt_public(self, message): m = BitArray(message.encode("latin-1")) n = self.n h = self.h t = int(m.length / h) mb = m.bin low = 0 up = h r = random.randint(1, n) xp = pow(r, 2, n) first = True for i in range(t): xp = pow(xp, 2, n) p = BitArray('0b' + bin(xp)).bin[0 - h:] c = BitArray('0b' + p) c ^= BitArray('0b' + mb[low:up]) if first: first = False ctext = c.copy() else: ctext.append(c) low += h up += h return (ctext.bytes.decode("latin-1"), pow(xp, 2, n))
def divide(dividend, divisor): # dividend ÷ divisor = quotient #HI = Remainder #LO = Quoitent print(dividend," / ", divisor) LO = BitArray(int = dividend, length = 32)#LO = Dividend print("quoitent = ", LO.bin) HI = BitArray(int = 0, length = 32)#HI = 0 print("remainder = ", HI.bin) for _ in range(32): req = HI.copy() req.append(LO) req <<= 1 LO = req[32:] print("quoitent << 1 ",LO.bin) HI = req[:32] print("remainder << 1 ",HI.bin) diff = HI.int - divisor if diff >= 0: print("diff > 0") HI = BitArray(int = diff, length = 32) print("remainder = ",HI.bin) LO.set(True, -1)#set lsb of LO as 1 print("quoitent = ", LO.bin) print("remainder = ", HI.int) print("quoitent = ", LO.int) print("res = ",LO.int,"+",HI.int,"/", divisor, " = ", LO.int+HI.int/divisor)
def hamming_search(b, bit, radius, current_radius, H): if current_radius == 0: H[current_radius].append(b.copy()) if current_radius == radius: return for i in range(bit+1, b.length): b2 = BitArray(b.copy()) b2.invert(i) H[current_radius+1].append(b2.copy()) hamming_search(b2, i, radius, current_radius+1, H)
def split(self, A): IG_list = [] A_count = float(A.count(True)) p_A = self.prob(A) e_A = self.entropy(p_A) # Get decision for node if p_A >= 0.5: d = 1 else: d = 0 # Check entropy of node if e_A < 0.3: print "Node entropy is low enough:", e_A return None,None,d,None,None # Check # elements if A_count < self.count_thresh: print "Node has few elements:", A_count return None,None,d,None,None F = self.X.T for f in range(len(F)): # Sort the relevant column and keep indices indices = F[f].argsort() pairs = zip(indices, F[f][indices]) s = len(pairs)*'0' B = BitArray(bin=s) C = A.copy() i = 0 IG_prev = 0.0 # Threshold emulator loop while i < len(pairs)-1: if A[pairs[i][0]]: B[pairs[i][0]] = 1 C[pairs[i][0]] = 0 if pairs[i][1] < pairs[i+1][1]: t = pairs[i+1][1] # Calculate information gain for the split IG_curr,s_B,s_C = self.info_gain(B,C,e_A,A_count) #print IG_curr if IG_curr < IG_prev: break else: IG_prev = IG_curr # Check if entropy for any branches is below thresh IG_list.append((IG_curr,f,t,d,B.copy(),C.copy(),s_B,s_C)) i += 1 if IG_list == []: #print "Boring decision..." return None,None,d,None,None else: max_val = max(IG[0] for IG in IG_list) IG,f,t,d,B,C,s_B,s_C = [IG for IG in IG_list if IG[0] == max_val][0] return f,t,d,B,C
def hamming_search(b, bit, radius, current_radius, H): if current_radius == 0: H[current_radius].append(b.copy()) if current_radius == radius: return for i in range(bit + 1, b.length): b2 = BitArray(b.copy()) b2.invert(i) H[current_radius + 1].append(b2.copy()) hamming_search(b2, i, radius, current_radius + 1, H)
def build_bitmaps_1(given, implied, nrAttributes): m = BitArray('0b'+'0'*2**nrAttributes) n = m.copy() n.invert() for j in range(nrAttributes): b = m.copy() step = 2**(j) a1=0 a2=a1+step for i in range(0,32,step): b[a1:a2] = n[a1:a2] a1=a2+step a2=a1+step given.append(b[:]) for j in range(nrAttributes): implied.append(given[j].copy()) for j in range(nrAttributes): implied[j].invert()
def Hmac(K, m): """ Computes the HMAC. Args: K: String representation of the key. m: String representation of the message. Returns: The computed HMAC. """ key = BitArray(K.encode("latin-1")) mess = BitArray(m.encode("latin-1")) #shortens key if its larger than the block size of SHA1 if (len(key.bin) > 512): key = BitArray(SHA1(key)) #pads the key to the size of a block in SHA1 if (len(key.bin) < 512): temp = BitArray('0b' + '0' * (512 - len(key.bin))) key.append(temp) #the outer pad opad = BitArray('0x5c') opad *= 64 o_key_pad = key.copy() o_key_pad ^= opad #the inner pad ipad = BitArray('0x36') ipad *= 64 i_key_pad = key.copy() i_key_pad ^= ipad #pads the message with two hashes result = i_key_pad.copy() result.append(mess) result = BitArray(SHA1(result)) temp = o_key_pad.copy() temp.append(result) return SHA1(temp).bytes.decode("latin-1")
def split(self, A): gain_list = [] A_count = float(A.count(True)) d = self.mean(A) if A_count <= self.count_thresh: print "Node has few elements:", A_count return None,None,d,None,None mse_A = self.mse([A]) #print "Curr mse:",mse_A F = self.X.T for f in range(len(F)): #print f # Sort the relevant column and keep indices indices = F[f].argsort() pairs = zip(indices, F[f][indices]) s = len(pairs)*'0' B = BitArray(bin=s) C = A.copy() i = 0 # Threshold emulator loop while i < len(pairs)-1: if A[pairs[i][0]]: B[pairs[i][0]] = 1 C[pairs[i][0]] = 0 if pairs[i][1] < pairs[i+1][1]: t = pairs[i+1][1] # Calculate MSE for the split mse_curr = self.mse([B,C]) gain_curr = mse_A - mse_curr # Check if entropy for any branches is below thresh gain_list.append((gain_curr,f,t,d,B.copy(),C.copy(),mse_A,mse_curr)) i += 1 if gain_list == []: print "mse_list empty" # return None,None,d,None,None else: max_val = max(mse[0] for mse in gain_list) gain,f,t,d,B,C,mse_A,mse_curr = [mse for mse in gain_list if mse[0] == max_val][0] if mse_curr <= 1.0: return None,None,d,None,None else: print "Gain:",mse_A,mse_curr return f,t,d,B,C
def evaluate_expr(expr, wordsIndex): """Evaluate the expression using the logical operations from BitArray. The expression must've been split in tokens. """ # Init variables result = BitArray(wordsIndex.files_count) initialised = False currentBits = BitArray(wordsIndex.files_count) negate = False state = '' iterator = enumerate(expr) for i, token in iterator: if token == '!': negate = True continue if re.match(OPERATORS, token): state = token continue if token == '(': closing_index = i + find_closing_paranthesis(expr[i:]) # Evaluate the expression between the parantheses currentBits = evaluate_expr(expr[i + 1:closing_index], wordsIndex).copy() # Jump with the iterator after the closing parantheses consume(iterator, closing_index - i) if is_word(token): if token in wordsIndex: currentBits = wordsIndex[token].copy() # Just ignore the stopwords elif token in STOPWORDS: negate = False currentBits = result.copy() else: # No match for the current word; Make all the bits 0 currentBits = BitArray(wordsIndex.files_count) result = apply_operator(result, currentBits, negate, state) negate = False state = None return result
class GifDataStream: def __init__(self, bytez): self.bytez = bytearray(bytez) self.remainder = BitArray() def read_uint(self, n): while len(self.remainder) < n: self.remainder.prepend(Bits(bytearray([self.bytez.pop(0)]))) uint = self.remainder.uint & (2**n - 1) self.remainder >>= n del self.remainder[0:n] return uint def peek_uint(self, n): s = self.remainder.copy() i = 0 while len(s) < n: s.prepend(Bits(bytearray(self.bytez[i:i + 1]))) i += 1 bits = Bits(s) return bits.uint & (2**n - 1)
args = parser.parse_args() if (len(args.command) != 12): print('command is wrong length') my_command = 'aXY1CT20F100' else: my_command = args.command in_preamble = BitArray('0b00000') in_device1 = BitArray('0xd70000c50027da11') in_device2 = BitArray('0x641000420027da11') in_params = BitArray('0xf40080c1002060060000b0002249000027da11') in_list = [in_preamble, in_device1, in_device2, in_params] #in_list[3].reverse() in_first = in_params.copy() print(in_list[0].bin) print(in_list[1].hex) print(in_list[2].hex) print(in_list[3].hex) #print(in_list[3].bin) in_list[0].clear() in_list[1].clear() in_list[2].clear() in_list[3].clear() with open(args.input, 'r') as raw_file: A_list1 = []
class PolynomialGenerator: def __init__(self, secret_bytes, degree, crc_length, gf_exp): """ :param secret_bytes: secret in bytes format :param degree: polynomial degree as int :param crc_length: CRC length as int :param gf_exp: exponential in GF(2**gf_exp) """ self.degree = degree self.crc_length = crc_length self.secret_bit = BitArray(bytes=secret_bytes, length=len(secret_bytes) * 8) self.gf_exp = gf_exp self.checksum_bit = BitArray(uint=binascii.crc32(self.secret_bit.bytes), length=self.crc_length) # join secret bitstring with CRC self.total_bit = self.secret_bit.copy() self.total_bit.append(self.checksum_bit) self.coefficients = self.extract_coefficients() # save polynomial in GF 2**32 form for performance reasons self.poly_gf_32 = GaloisConverter.convert_int_list_to_gf_2_list(self.coefficients, 32) # save galois field K for polynomial evaluations self.K = GF(2, gf_exp) def prune_secret(self, secret_bit): """ Prunes secret if secret length + CRC length is not multiple of polynomial degree + 1. Takes secret as BitArray :returns pruned secret as Bitarray """ # check if bitstring has multiple of length of polynomial degree # secret is pruned if length don't match multiple of polynomial degree + 1 remainder = (len(secret_bit) + self.crc_length) % (self.degree + 1) secret_len = len(secret_bit) - remainder if remainder == 0: return secret_bit else: return secret_bit[0:secret_len] def extract_coefficients(self): """ extracts coefficients of polynomial from bitstring :returns coefficients as list """ # split to parts, convert to uint and add to list coefficients = [] assert len(self.total_bit) % (self.degree + 1) == 0 step = int(len(self.total_bit) / (self.degree + 1)) for i in range(0, len(self.total_bit), step): # print(len(self.total_bit[i:i + step])) # print(self.total_bit[i:i + step].bin) # print(self.total_bit[i:i + step].uint) coefficients.append(self.total_bit[i:i + step].uint) return coefficients def evaluate_polynomial_gf_2(self, x): """ Evaluate polynomial of this polynomial generator at x in GF(2**m) :param x: int :param m: exponential in GF(2**m) :returns function result as int """ m = self.gf_exp if m == 32: poly_gf = self.poly_gf_32 else: poly_gf = GaloisConverter.convert_int_list_to_gf_2_list(self.coefficients, m) x_gf = GaloisConverter.convert_int_to_element_in_gf_2(x, m) y_gf = self.K.eval_poly(poly_gf, x_gf) result = GaloisConverter.convert_gf_2_element_to_int(y_gf, m) # Safety check if result > 2**m*2: raise ValueError('Too large number generated in polynomial GF(2**{}):{}'.format(m, result)) return result def evaluate_polynomial_gf_2_array(self, array): """ Evaluate polynomial on list of integers :param array: list of integers :param m: exponential in GF(2**m) """ result = [] for x in array: result.append(self.evaluate_polynomial_gf_2(x)) return result
class FileMgr(object): def __init__(self, metainfo): self._metainfo = metainfo self._have = BitArray(self._metainfo.num_pieces) directory = metainfo.directory if directory != "": try: if not os.path.exists(directory): os.makedirs(directory) except OSError as err: if err.errno != errno.EEXIST: raise files = metainfo.files # _files is a list of files in the torrent. Each entry is a # tuple containing the file descriptor, length of the file and # offset of the file within the torrent self._files = [] offset = 0 subdirs = [] for path, length in files: dirname = directory + "/".join(path[0:-1]) if dirname != "" and dirname not in subdirs: subdirs.append(dirname) try: if not os.path.exists(dirname): os.makedirs(dirname) except OSError as err: if err.errno != errno.EEXIST: raise if dirname == "": filename = path[-1] else: filename = dirname + "/" + path[-1] try: open(filename, "a").close() fd = open(filename, "rb+") except IOError: logger.critical("Unable to open file {}".format(filename)) raise self._files.append((fd, length, offset)) offset += length def _file_index(self, offset): for i, (fd, length, begin) in enumerate(self._files): if offset >= begin and offset < begin + length: return i def have(self): return self._have.copy() def write_block(self, piece_index, offset_in_piece, buf, file_index=None): offset_in_torrent = piece_index * self._metainfo.piece_length + offset_in_piece if file_index is None: file_index = self._file_index(offset_in_torrent) fd, file_length, file_offset_in_torrent = self._files[file_index] offset_in_file = offset_in_torrent - file_offset_in_torrent fd.seek(offset_in_file) if len(buf) <= file_length - offset_in_file: fd.write(buf) fd.flush() else: to_write = file_length - offset_in_file fd.write(buf[:to_write]) fd.flush() self.write_block(piece_index, offset_in_piece + to_write, buf[to_write:], file_index + 1)
def split(self, A): gain_list = [] A_count = float(A.count(True)) d = self.mean(A) if A_count <= self.count_thresh: #print "Node has few elements:", A_count return None,None,d,None,None mse_A = self.mse([A]) #if mse_A <= 15: # print "Node has small MSE:", mse_A # return None,None,d,None,None print "Elem, MSE:",A_count,mse_A F = self.X.T for f in range(len(F)): #print f # Sort the relevant column and keep indices indices = F[f].argsort() pairs = zip(indices, F[f][indices]) s = len(pairs)*'0' B = BitArray(bin=s) C = A.copy() i = 0 gain_prev = 0.0 # Threshold emulator loop while i < len(pairs)-1: if A[pairs[i][0]]: B[pairs[i][0]] = 1 C[pairs[i][0]] = 0 if pairs[i][1] < pairs[i+1][1]: t = pairs[i+1][1] # Calculate MSE for the split mse_curr = self.mse([B,C]) gain_curr = mse_A - mse_curr if gain_curr < 0: print gain_curr #print mse_curr if gain_curr < gain_prev: pass #break else: gain_prev = gain_curr # Check if entropy for any branches is below thresh if B.count(True) == 0 or C.count(True) == 0: pass else: gain_list.append((gain_curr,f,t,d,B.copy(),C.copy(),mse_A,mse_curr)) i += 1 if gain_list == []: print "mse_list empty" return None,None,d,None,None else: max_val = max(mse[0] for mse in gain_list) gain,f,t,d,B,C,mse_A,mse_curr = [mse for mse in gain_list if mse[0] == max_val][0] if B.count(True) == 0 or C.count(True) == 0: print "Count of B or C = 0:",B.count(True), C.count(True) for elem in gain_list: print elem[4].count(True), elem[5].count(True) print return None,None,d,None,None else: return f,t,d,B,C
class Genes: """ This class is responsible for abstracting and taking care of genes. The idea behind chromosome array is that it consists of bits representing reactions to different situations on board. We have 1,048,576 possible situations on board (in upper two rows with tetrominoes) and 7 different tetromino types. We have to choose position and number of rotations of tetromino for each situation. We have 4 possible rotations and 7 possible tetromino shapes. Array will be constructed in such a way, that: 42 bits will represent all possible reactions to given situations on board 42b = 6b * 7 6b = 2b for rotation + 4b for position 7 is a number of possible tetrominoes and the whole array will have 44,040,192 bits = 5.25 MB 42 * 1,048,576 42 possible reaction to each situations 1,048,576 situations """ # number of possible different situations in first two rows in which tetrominoes are <0,10448575> SITUATIONS_NUM: int = 1048576 # number of possible tetromino rotations <0,3> ROTATIONS_NUM: int = 4 # number of possible different tetrominoes <0,6> TETROMINOES_NUM: int = 7 # number of possible positions for x coordinate of left tetromino's side <0,9> POSITIONS_NUM: int = 10 # number of bits needed to encode possible rotations ROTATION_BITS_LEN: int = 2 # number of bits needed to encode possible positions POSITION_BITS_LEN: int = 4 # number of bits needed to encode possible reactions to given tetromino in given situation TETROMINO_BITS_LEN: int = ROTATION_BITS_LEN + POSITION_BITS_LEN # number of bits needed to encode possible reactions to all tetrominoes in given situation SITUATION_BITS_LEN: int = TETROMINO_BITS_LEN * TETROMINOES_NUM # length of the whole chromosome CHROMOSOME_LEN: int = SITUATION_BITS_LEN * SITUATIONS_NUM # used to init random chromosome MAX_INT_REPRESENTING_CHROMOSOME = (2**(SITUATIONS_NUM * SITUATION_BITS_LEN)) - 1 # @classmethod def get_random(cls): """ Creates new Gene with random chromosome. :return: new Gene object with random chromosome """ new = Genes() init = randint(0, cls.MAX_INT_REPRESENTING_CHROMOSOME) new.chromosomes = BitArray(uint=init, length=cls.CHROMOSOME_LEN) return new @classmethod def from_file(cls, file: str): """ Creates new Gene with chromosome read from file. :param file: path to file from which chromosome will be read :return: new Gene object with chromosome read from file """ new = Genes() new.chromosomes = BitArray(filename=file) return new def __init__(self): """ Creates new Gene object with chromosome composed of zeros and with proper length. """ self.chromosomes = BitArray(length=self.CHROMOSOME_LEN) def copy(self): """ Returns new Gene object being copy of self :return: new Gene object """ new = Genes() new.chromosomes = self.chromosomes.copy() return new # def get_rotation(self, situation: BitArray, tetromino_num: int): """ Returns number of rotations for given tetromino in given situation :param situation: BitArray object representing situation in two upper rows with tetrominoes :param tetromino_num: int representing number of shape of tetromino :return: int representing number of rotations for given tetromino in given situation """ reaction = self.__get_reaction(situation, tetromino_num) starting_point = 0 ending_point = self.ROTATION_BITS_LEN return reaction[starting_point:ending_point].uint def get_position(self, situation: BitArray, tetromino_num: int): """ Returns position for given tetromino in given situation :param situation: BitArray object representing situation in two upper rows with tetrominoes :param tetromino_num: int representing number of shape of tetromino :return: int representing position for given tetromino in given situation """ reaction = self.__get_reaction(situation, tetromino_num) starting_point = self.ROTATION_BITS_LEN ending_point = starting_point + self.POSITION_BITS_LEN return reaction[starting_point:ending_point].uint % self.POSITIONS_NUM def mutate(self): """ Mutates chromosome by taking random number of mutations (0, max number of mutation from config) and mutating random rotation and other random position given number of times """ max_mutations_num = get_mutations_num() mutations_num = randint(0, max_mutations_num) for i in range(mutations_num): self.__mutate_rotation( Genes.__get_situation_from_number( randint(0, self.SITUATIONS_NUM - 1))) self.__mutate_position( Genes.__get_situation_from_number( randint(0, self.SITUATIONS_NUM - 1))) # @staticmethod def __get_situation_from_number(situation_num: int): """ Creates BitArray object representing situation from int representing situation TODO: "Situation" should be moved to separate class :param situation_num: int representing situation :return: new BitArray object representing situation """ return BitArray(uint=situation_num, length=20) def __set_rotation(self, situation: BitArray, tetromino_num: int, rotations_num: int): """ Sets number of rotations for given tetromino in given situation. :param situation: situation in which tetromino's number of rotations will be set :param tetromino_num: number representing shape of tetromino :param rotations_num: number of rotations """ if rotations_num > 3: raise ValueError("Rotations are in range <0, 3>, not " + str(rotations_num)) first_rotation_index = self.__get_reaction_index( situation, tetromino_num) if rotations_num == 0: self.chromosomes[first_rotation_index] = 0 self.chromosomes[first_rotation_index + 1] = 0 elif rotations_num == 1: self.chromosomes[first_rotation_index] = 0 self.chromosomes[first_rotation_index + 1] = 1 elif rotations_num == 2: self.chromosomes[first_rotation_index] = 1 self.chromosomes[first_rotation_index + 1] = 0 elif rotations_num == 3: self.chromosomes[first_rotation_index] = 1 self.chromosomes[first_rotation_index + 1] = 1 def __set_position(self, situation: BitArray, tetromino_num: int, position: int): """ Sets position for given tetromino in given situation. :param situation: situation in which tetromino's position will be set :param tetromino_num: number representing shape of tetromino :param position: int representing position """ if position > 9: raise ValueError("Positions are in range <0, 9>, not " + str(position)) first_position_index = self.__get_reaction_index( situation, tetromino_num) + self.ROTATION_BITS_LEN if position == 0: self.chromosomes[first_position_index] = 0 self.chromosomes[first_position_index + 1] = 0 self.chromosomes[first_position_index + 2] = 0 self.chromosomes[first_position_index + 3] = 0 elif position == 1: self.chromosomes[first_position_index] = 1 self.chromosomes[first_position_index + 1] = 0 self.chromosomes[first_position_index + 2] = 0 self.chromosomes[first_position_index + 3] = 0 elif position == 2: self.chromosomes[first_position_index] = 0 self.chromosomes[first_position_index + 1] = 1 self.chromosomes[first_position_index + 2] = 0 self.chromosomes[first_position_index + 3] = 0 elif position == 3: self.chromosomes[first_position_index] = 1 self.chromosomes[first_position_index + 1] = 1 self.chromosomes[first_position_index + 2] = 0 self.chromosomes[first_position_index + 3] = 0 elif position == 4: self.chromosomes[first_position_index] = 0 self.chromosomes[first_position_index + 1] = 0 self.chromosomes[first_position_index + 2] = 1 self.chromosomes[first_position_index + 3] = 0 elif position == 5: self.chromosomes[first_position_index] = 1 self.chromosomes[first_position_index + 1] = 0 self.chromosomes[first_position_index + 2] = 1 self.chromosomes[first_position_index + 3] = 0 elif position == 6: self.chromosomes[first_position_index] = 0 self.chromosomes[first_position_index + 1] = 1 self.chromosomes[first_position_index + 2] = 1 self.chromosomes[first_position_index + 3] = 0 elif position == 7: self.chromosomes[first_position_index] = 1 self.chromosomes[first_position_index + 1] = 1 self.chromosomes[first_position_index + 2] = 1 self.chromosomes[first_position_index + 3] = 0 elif position == 8: self.chromosomes[first_position_index] = 0 self.chromosomes[first_position_index + 1] = 0 self.chromosomes[first_position_index + 2] = 0 self.chromosomes[first_position_index + 3] = 1 elif position == 9: self.chromosomes[first_position_index] = 1 self.chromosomes[first_position_index + 1] = 0 self.chromosomes[first_position_index + 2] = 0 self.chromosomes[first_position_index + 3] = 1 def __mutate_rotation(self, situation: BitArray): """ Mutates random rotation for given situation :param situation: BitArray representing situation """ tetromino_to_mutate = randint(0, 6) prev_rotation = self.get_rotation(situation, tetromino_to_mutate) new_rotation = (prev_rotation - 1) % self.ROTATIONS_NUM self.__set_rotation(situation, tetromino_to_mutate, new_rotation) def __mutate_position(self, situation: BitArray): """ Mutates random position for given situation :param situation: BitArray representing situation """ tetromino_to_mutate = randint(0, 6) prev_position = self.get_rotation(situation, tetromino_to_mutate) new_position = (prev_position - 1) % self.POSITIONS_NUM self.__set_position(situation, tetromino_to_mutate, new_position) def __get_reaction(self, situation: BitArray, tetromino_num: int): starting_index = self.__get_reaction_index(situation, tetromino_num) ending_index = starting_index + self.TETROMINO_BITS_LEN return self.chromosomes[starting_index:ending_index] def __get_reaction_index(self, situation: BitArray, tetromino_num: int): situation_int = situation.uint return (situation_int * self.SITUATION_BITS_LEN) + ( tetromino_num * self.TETROMINO_BITS_LEN)
class Message(object): def __init__(self, message_bit_array=BitArray(length=256)): """ :param message_bit_array: message BitArray :type message_bit_array: BitArray """ self.message_block_amount = 8 self.normal_message_bits_amount = 256 self.message_bit_array = message_bit_array self.message = self.message_bit_array.tobytes() self._normalize_message() @classmethod def get_message_from_message_blocks(cls, message_blocks): message_bit_array = BitArray() for message_block in message_blocks: message_bit_array.append(message_block.message_block) return Message(message_bit_array) def set_message_as_string(self, message_string): self.message = message_string self.message_bit_array = BitArray(self.message_to_hex(message_string)) def message_to_hex(self, message_string): return '0x' + ''.join(x.encode('hex') for x in message_string) def _normalize_message(self): if self.message_bit_array.length > self.normal_message_bits_amount: self._trim_message() def _trim_message(self): self.message_bit_array = self.message_bit_array[0:self.normal_message_bits_amount] def get_message_blocks(self): message_bit_array = self.message_bit_array.copy() message_blocks = [] message_block_size = self.normal_message_bits_amount / self.message_block_amount padding_blocks_amount = ( self.normal_message_bits_amount - message_bit_array.length) / message_block_size padding_bits_amount = (self.normal_message_bits_amount - message_bit_array.length) % message_block_size if padding_bits_amount != 0: padding_block = BitArray('0b' + ''.join('0' for x in range(0, padding_bits_amount))) message_bit_array.prepend(padding_block) for padding_block_index in range(0, padding_blocks_amount): message_block = BitArray('0b00000000000000000000000000000000') message_blocks.append(MessageBlock(message_block)) for message_block_index in range(0, self.message_block_amount - padding_blocks_amount): message_block = message_bit_array[ message_block_index * message_block_size:message_block_index * message_block_size + message_block_size] message_blocks.append(MessageBlock(message_block)) return message_blocks def __unicode__(self): return self.message def __str__(self): return self.__unicode__()
class LDevice: # Обертка над C API def __init__(self, slot): self._closed = True err = ffi.new("unsigned int*") device = _dll.CreateLDevice(slot, err) err = err[0] if device == ffi.NULL: if err == 1: raise LDeviceError("CreateLDevice return L_NOTSUPPORTED") elif err == 2: raise LDeviceError("CreateLDevice return L_ERROR") elif err == 3: raise LDeviceError("CreateLDevice return L_ERROR_NOBOARD") elif err == 4: raise LDeviceError("CreateLDevice return L_ERROR_INUSE") else: raise AssertionError("Unknown error number {}".format(err)) if _dll.OpenLDevice(device) == L_ERROR: _dll.ReleaseLDevice(device) raise LDeviceError("OpenLDevice error") self._closed = False self._impl = device self._ttl = BitArray(uint=0, length=16) def close(self): assert not self._closed self._closed = True print("Close LDevice") try: if _dll.CloseLDevice(self._impl) == L_ERROR: raise LDeviceError("CloseLDevice error") finally: _dll.ReleaseLDevice(self._impl) def __del__(self): if not self._closed: self.close() def plata_test(self): return _dll.PlataTest(self._impl) == L_SUCCESS def init_start(self): if _dll.InitStartLDevice(self._impl) == L_ERROR: raise LDeviceError("InitStartLDevice error") def start(self): if _dll.StartLDevice(self._impl) == L_ERROR: raise LDeviceError("StartLDevice error") def stop(self): if _dll.StopLDevice(self._impl) == L_ERROR: raise LDeviceError("StopLDevice error") def load_bios(self, filename): assert type(filename) == str filename = filename.encode("ascii") if _dll.LoadBios(self._impl, filename) == L_ERROR: raise LDeviceError("LoadBios error") def create_WASYNC_PAR(self): return ffi.new("WASYNC_PAR*") def io_async(self, WASYNC_PAR): if _dll.IoAsync(self._impl, WASYNC_PAR) == L_ERROR: raise LDeviceError("IoAsync error") def get_slot_param(self): sp = ffi.new("SLOT_PAR*") if _dll.GetSlotParam(self._impl, sp) == L_ERROR: raise LDeviceError("GetSlotParam error") return sp def enable_correction(self, val): assert type(val) == bool if _dll.EnableCorrection(self._impl, int(val)) == L_ERROR: raise LDeviceError("EnableCorrection error") # Пользовательские функции @property def ttl(self): return self._ttl def ttl_enable(self, enabled: bool): sp = self.create_WASYNC_PAR() sp.s_Type = L_ASYNC_TTL_CFG sp.Mode = int(enabled) self.io_async(sp) def ttl_write(self): sp = self.create_WASYNC_PAR() sp.s_Type = L_ASYNC_TTL_OUT ttl = self._ttl.copy() ttl.reverse() sp.Data[0] = ttl.uint self.io_async(sp) def ttl_read(self): sp = self.create_WASYNC_PAR() sp.s_Type = L_ASYNC_TTL_INP self.io_async(sp) ret = BitArray(uint=sp.Data[0], length=16) ret.reverse() return ret def adc_get(self, num): assert (num >= 0) and (num < 16) sp = self.create_WASYNC_PAR() sp.s_Type = L_ASYNC_ADC_INP sp.Chn[0] = num self.io_async(sp) value = Bits(uint=sp.Data[0], length=16) return value.int
def main(): file = open(sys.argv[1], "rb") msg = ConstBitStream(file) s_in = BitArray() aux = BitArray() keys = [''] s_out = '' s_in.append(msg.read(1)) aux = s_in.copy() aux.invert(0) count = 0 #Encontrar o tamanho do padding while (s_in.bin) != aux.bin: try: count += 1 s_in.clear() s_in.append(msg.read(1)) except ReadError: break padding = BitArray() padding.append(s_in) s_in = BitArray() #Com o tamanho encontrar o padding correspondente padding.append(msg.read(count - 1)) while True: n_bits = ceil(log2(len(keys))) try: s_in.append(msg.read(n_bits + 1)) except ReadError: break y = s_in[:-1] b = s_in[-1:] if Bits(y) == Bits(''): pos = 0 else: pos = y.uint s_out = s_out + (str(keys[pos]) + b.bin) keys.append(str(keys[pos]) + str(Bits(b).bin)) s_in = BitArray() output = BitArray('0b' + s_out) output.append(padding) with open(sys.argv[2], 'wb') as f_out: output.tofile(f_out) file.close()
#generate KS KS = BitArray(uint=random.randint(0, 1023), length=10) IDA = BitArray('0b' + M1.bin[:16]) IDB = BitArray('0b' + M1.bin[16:32]) T = int(time.time()) leng = len(bin(T)) rem = leng % 8 if (rem <= 6): leng += (6 - rem) else: leng += 7 BT = BitArray(uint=T, length=leng) M2 = KS.copy() M2.append(IDB) M2.append(BT) M3 = KS.copy() M3.append(IDA) M3.append(BT) enM3 = multDES(M3, KB, 0) M2.append(enM3) enM2 = multDES(M2, KA, 0) #sending M2 to Alice AKDC.send(enM2.bytes)
class FileMgr(object): def __init__(self, metainfo): self._metainfo = metainfo self._have = BitArray(self._metainfo.num_pieces) directory = metainfo.directory if directory != '': try: if not os.path.exists(directory): os.makedirs(directory) except OSError as err: if err.errno != errno.EEXIST: raise files = metainfo.files # _files is a list of files in the torrent. Each entry is a # tuple containing the file descriptor, length of the file and # offset of the file within the torrent self._files = [] offset = 0 subdirs = [] for path, length in files: dirname = directory+"/".join(path[0:-1]) if dirname != '' and dirname not in subdirs: subdirs.append(dirname) try: if not os.path.exists(dirname): os.makedirs(dirname) except OSError as err: if err.errno != errno.EEXIST: raise if dirname == '': filename = path[-1] else: filename = dirname+"/"+path[-1] try: open(filename, 'a').close() fd = open(filename, 'rb+') except IOError: logger.critical("Unable to open file {}".format(filename)) raise self._files.append((fd, length, offset)) offset += length def _file_index(self, offset): for i, (fd, length, begin) in enumerate(self._files): if offset >= begin and offset < begin + length: return i def have(self): return self._have.copy() def write_block(self, piece_index, offset_in_piece, buf, file_index=None): offset_in_torrent = (piece_index * self._metainfo.piece_length + offset_in_piece) if not file_index: file_index = self._file_index(offset_in_torrent) fd, file_length, file_offset_in_torrent = self._files[file_index] offset_in_file = offset_in_torrent - file_offset_in_torrent fd.seek(offset_in_file) if len(buf) <= file_length - offset_in_file: fd.write(buf) fd.flush() else: to_write = file_length - offset_in_file fd.write(buf[:to_write]) fd.flush() self.write_block(piece_index, offset_in_piece + to_write, buf[to_write:], file_index+1)
args = parser.parse_args() if (len(args.command) != 12): print('command is wrong length') my_command = 'aXY1CT20F100' else: my_command =args.command in_preamble = BitArray('0b00000') in_device1 = BitArray('0xd70000c50027da11') in_device2 = BitArray('0x641000420027da11') in_params = BitArray('0xf40080c1002060060000b0002249000027da11') in_list = [in_preamble,in_device1,in_device2,in_params] #in_list[3].reverse() in_first = in_params.copy() print(in_list[0].bin) print(in_list[1].hex) print(in_list[2].hex) print(in_list[3].hex) #print(in_list[3].bin) in_list[0].clear() in_list[1].clear() in_list[2].clear() in_list[3].clear() with open(args.input, 'r') as raw_file: A_list1 = []
class CamelliaKey(object): """ @brief In this function, we initialize the object @:param length length of the camellia key @:param ckey_adress camellia private key file address (need to be a Ox number) @:var KL (key left block), KR (key right block) @:var ckey (content of the file at the file adress ckey_adress) """ def __init__(self, ckey_address, length): self.length = length if self.length not in [128, 192, 256]: raise ValueError("Invalid key length, " "it must be 128, 192 or 256 bits long!") file = open(ckey_address, "r") ckey = file.read() file.close() # ckey is a BitArray Object ckey = BitArray(ckey) if self.length == 128: self.KL = ckey self.KR = BitArray(Bits(int=0, length=128)) elif self.length == 192: self.KL = re_128b(ckey >> 64) a = (ckey & MASK64_192) << 64 b = ~(ckey & MASK64_192) b.replace("0xffffffffffffffff", "0x0000000000000000") self.KR = re_128b(a | b) elif self.length == 256: self.KL = re_128b(ckey >> 128) self.KR = re_128b(ckey & MASK128) else: print("what the f**k") def generate_ka(self): """ @brief Generate KA @:return ka :rtype: BitArray object """ # mise en 64 bits car f_function n'autorise que les entrées de 64bits et les ^ n'est autorisée que sur des # bytearray de même taille a = self.KL ^ self.KR temp1 = re_64b(a >> 64) temp2 = re_64b(a & MASK64) temp2 ^= f_function(temp1, sigma[0]) temp1 ^= f_function(temp2, sigma[1]) temp1 ^= re_64b((self.KL >> 64)) temp2 ^= re_64b((self.KL & MASK64)) temp2 ^= f_function(temp1, sigma[2]) temp1 ^= f_function(temp2, sigma[3]) # remise en 128 bits temp1 = agg_128b(temp1) temp2 = agg_128b(temp2) ka = (temp1 << 64) | temp2 return ka """ @brief Generate KB @:return kb """ def generate_kb(self): """ :rtype: BitArray """ if self.length != 128: ka = self.generate_ka() temp1 = re_64b((ka ^ self.KR) >> 64) temp2 = re_64b((ka ^ self.KR) & MASK64) temp2 ^= f_function(temp1, sigma[4]) temp1 ^= f_function(temp2, sigma[5]) temp1 = agg_128b(temp1) temp2 = agg_128b(temp2) kb = (temp1 << 64) | temp2 else: kb = BitArray(Bits(int=0, length=128)) return kb """ @brief Generate all the subkeys for the encryption with a Camellia Key @:return a table of subkeys """ def generate_subkeys(self): ka = self.generate_ka() if self.length == 128: k1 = ka >> 64 k2 = ka & MASK64 klc15 = self.KL.copy() klc15.rol(15) k3 = klc15 >> 64 k4 = klc15 & MASK64 kac15 = ka.copy() kac15.rol(15) k5 = kac15 >> 64 k6 = kac15 & MASK64 klc45 = self.KL.copy() klc45.rol(45) k7 = klc45 >> 64 k8 = klc45 & MASK64 kac45 = ka.copy() kac45.rol(45) k9 = kac45 >> 64 klc60 = self.KL.copy() klc60.rol(60) k10 = klc60 & MASK64 kac60 = ka.copy() kac60.rol(60) k11 = kac60 >> 64 k12 = kac60 & MASK64 klc94 = self.KL.copy() klc94.rol(94) k13 = klc94 >> 64 k14 = klc94 & MASK64 kac94 = ka.copy() kac94.rol(94) k15 = kac94 >> 64 k16 = kac94 & MASK64 klc111 = self.KL.copy() klc111.rol(111) k17 = klc111 >> 64 k18 = klc111 & MASK64 subk128 = [ k1, k2, k3, k4, k5, k6, k7, k8, k9, k10, k11, k12, k13, k14, k15, k16, k17, k18 ] return re_64b_array(subk128) else: kb = self.generate_kb() k1 = kb >> 64 k2 = kb & MASK64 krc15 = self.KR.copy() krc15.rol(15) k3 = krc15 >> 64 k4 = krc15 & MASK64 kac15 = ka.copy() kac15.rol(15) k5 = kac15 >> 64 k6 = kac15 & MASK64 kbc30 = kb.copy() kbc30.rol(30) k7 = kbc30 >> 64 k8 = kbc30 & MASK64 klc45 = self.KL.copy() klc45.rol(45) k9 = klc45 >> 64 k10 = klc45 & MASK64 kac45 = ka.copy() kac45.rol(45) k11 = kac45 >> 64 k12 = kac45 & MASK64 krc60 = self.KR.copy() krc60.rol(60) k13 = krc60 >> 64 k14 = krc60 & MASK64 kbc60 = kb.copy() kbc60.rol(60) k15 = kbc60 >> 64 k16 = kbc60 & MASK64 klc77 = self.KL.copy() klc77.rol(77) k17 = klc77 >> 64 k18 = klc77 & MASK64 krc94 = self.KR.copy() krc94.rol(94) k19 = krc94 >> 64 k20 = krc94 & MASK64 kac94 = ka.copy() kac94.rol(94) k21 = kac94 >> 64 k22 = kac94 & MASK64 klc111 = self.KL.copy() klc111.rol(111) k23 = klc111 >> 64 k24 = klc111 & MASK64 subk = [ k1, k2, k3, k4, k5, k6, k7, k8, k9, k10, k11, k12, k13, k14, k15, k16, k17, k18, k19, k20, k21, k22, k23, k24 ] return re_64b_array(subk) def generate_subkw(self): """ @:brief Generate_subkw aims to generate all the subkeys kw1, kw2, kw3 and kw4. @:return a table of subkweys """ if self.length == 128: k = self.generate_ka() else: k = self.generate_kb() kw1 = self.KL >> 64 kw2 = self.KL & MASK64 kc = k.copy() kc.rol(111) kw3 = kc >> 64 kw4 = kc & MASK64 subkweys = [kw1, kw2, kw3, kw4] return re_64b_array(subkweys) def generate_subke(self): """ @:brief Generate_subke aims to generate all the subkeys ke1, ke2, ke3, etc... this subkeys are different if the length of the key is 128 or if it is different @:return a table of all the subkeys """ ka = self.generate_ka() if self.length == 128: # make copy of ka to use rotation left kac = ka.copy() klc = self.KL.copy() # use rotation left, the result become the var kac.rol(30) klc.rol(77) ke1 = kac >> 64 ke2 = kac & MASK64 ke3 = klc >> 64 ke4 = klc & MASK64 subke128 = [ke1, ke2, ke3, ke4] return re_64b_array(subke128) else: krc = self.KR.copy() krc.rol(30) ke1 = krc >> 64 ke2 = krc & MASK64 klc = self.KL.copy() klc.rol(60) ke3 = klc >> 64 ke4 = klc & MASK64 kac = ka.copy() kac.rol(77) ke5 = kac >> 64 ke6 = kac & MASK64 subke = [ke1, ke2, ke3, ke4, ke5, ke6] return re_64b_array(subke)
def SHA1(m): """ SHA1 hash function. Args: m: The message, as a BitArray. Returns: The message hash, as a BitArray. """ #initialising variables for use in Hash mt = BitArray(m) h0 = BitArray('0x67452301') h1 = BitArray('0xEFCDAB89') h2 = BitArray('0x98BADCFE') h3 = BitArray('0x10325476') h4 = BitArray('0xC3D2E1F0') #processing message so that it fits Hash Format m1 = len(mt.bin) m2 = m1 if m1%8 == 0: m2 += 1 mt.append(BitArray('0b1')) #more processing by adding a pad so message is divisible into 512 bit chunks temp_len = m2%512 pad = 0 if temp_len < 448: pad = 448-temp_len else: pad = (512-temp_len) + 448 padding = BitArray('0b'+'0'*pad) padding.append(BitArray(uint=m1,length=64)) mt.append(padding) pad_len = len(mt.bin) Imin = 0 Imax = 512 #breaks message into 512 bit chunks and works on each one while Imax <= pad_len: block = BitArray('0b'+mt.bin[Imin:Imax]) #splits 512 bit chunk into 16, 32 bit chunks w = [0]*80 low = 0 up = 16 for i in range(16): w[i] = BitArray('0b'+block.bin[low:up]) low +=16 up += 16 #then expands to 80 32 bit chunks for i in range(16,80): temp_BA = w[i-3].copy() temp_BA ^= w[i-8] temp_BA ^= w[i-14] temp_BA ^= w[i-16] temp_BA.rol(1) w[i] = temp_BA.copy() #initialize hash values for this chunk a = h0.copy() b = h1.copy() c = h2.copy() d = h3.copy() e = h4.copy() for i in range(0,80): #the F function used if 0 <= i <20: tb = b.copy() tb &= c ntb = b.copy() ntb.invert() ntb &= d tb |= ntb fun = tb.copy() k = BitArray('0x5A827999') elif 20 <= i <40: tb = b.copy() tb ^= c tb ^= d fun = tb.copy() k = BitArray('0x6ED9EBA1') elif 40 <= i < 60: tb = b.copy() tb &= c ttb = b.copy() ttb &= d tc = c.copy() tc &= d tb |= ttb tb |= tc fun = tb.copy() k = BitArray('0x8F1BBCDC') elif 60 <= i < 80: tb = b.copy() tb ^= c tb ^= d fun = tb.copy() k = BitArray('0xCA62C1D6') temp = a.copy() temp.rol(5) temp_val = (temp.uint + fun.uint + e.uint + k.uint + w[i].uint)% 2**32 temp = BitArray(uint = temp_val,length = 32) e = d.copy() d = c.copy() c = b.copy() c.rol(30) b = a.copy() a = temp.copy() #updates h0,h1,h2,h3,h4 so as to cause avalanche effect tval = (h0.uint + a.uint)% 2**32 h0 = BitArray(uint = tval,length = 32) tval = (h1.uint + b.uint)% 2**32 h1 = BitArray(uint = tval,length = 32) tval = (h2.uint + c.uint)% 2**32 h2 = BitArray(uint = tval,length = 32) tval = (h3.uint + d.uint)% 2**32 h3 = BitArray(uint = tval,length = 32) tval = (h4.uint + e.uint)% 2**32 h4 = BitArray(uint = tval,length = 32) Imin += 512 Imax += 512 #combines into 160 bit hash value and returns hh = h0.copy() hh.append(h1) hh.append(h2) hh.append(h3) hh.append(h4) return hh
class Framing(): """Classe que representa o procedimento para alinhamento de quadro no PCM30 """ def __init__(self, logging_level=logging.INFO): self.buffer_octeto = BitArray( ) # Buffer utilizado somente no Estado Realinhando self.buffer_frame = BitArray() self.buffer_copy = BitArray() self.n = 1 # número de quadros para avançar (inicia em 1) # Configurando Logs self.logger = logging.getLogger("Framming") logging.basicConfig(level=logging_level) # Definindo estado inicial self.logger.info("Iniciando...") self.state = State.REALIGNING self._print_state() self.logger.info("Procurando FAS...") # Método chamado pela função principal def handle_fsm(self, received_bit: bin): """Método para chamar a Máquina de estados passando os bits recebidos externamente ou bits presentes no buffer. Args: received_bit (bin): bit 0 <'0b0'> ou 1 <'0b1'> """ self._fsm(received_bit) # Após retornar da FSM só volta a ler o arquivo se o buffer tiver vazio while len(self.buffer_copy) > 0: # Enquanto tiver bits no buffer buffer_bit = self.buffer_copy.bin[0] del self.buffer_copy[0:1:1] self._fsm(self.char_to_bit(buffer_bit)) def _fsm(self, buffer_bit): """Método privado que representa a máquina de estados Args: received_bit : bit recebido """ # Estado REALINHANDO if self.state is State.REALIGNING: len_octeto = len(self.buffer_octeto) if len_octeto < 8: self.buffer_octeto.append(buffer_bit) else: # Deslizar octeto del self.buffer_octeto[0:1:1] # Remove bit da primeira posição self.buffer_octeto.append( buffer_bit) # Insere novo bit na última self.logger.debug("Octeto: %s" % self.buffer_octeto.bin) if self.buffer_octeto.uint is Signal.FAS.value: # Verifica se temos um possível PAQ self.logger.info("FAS confirmado, possível PAQ encontrado!") self.state = State.REALIGNMENT_CHECK # Transição de Estado self._print_state() # Estado de confirmação de Realinhamento elif self.state is State.REALIGNMENT_CHECK: frame, octeto = self._go_to_frame(self.n, buffer_bit) if frame == 1: # Avançou 1 quadro b1_pos = 1 b1 = octeto.bin[b1_pos] # Recuperando b1 para comparação self.logger.info("b1 (nfas) = %s" % b1) self.logger.debug("Buffer = %s" % self.buffer_frame.bin) if str(b1) == '1': # comparação do b1 self.logger.info("NFAS confirmado!") self.logger.debug("Buffer = %s" % self.buffer_frame.bin) self.n = 2 # avançar para próximo quadro else: self.logger.info("NFAS não confirmado, PAQ Inválido!") self.state = State.REALIGNING # Transição de Estado self.buffer_copy.clear() self.buffer_copy = self.buffer_frame.copy() self.logger.debug("Buffer Copy= %s" % self.buffer_copy.bin) self.buffer_frame.clear() self.n = 1 self._print_state() self.logger.info("Procurando FAS...") elif frame == 2: # Avançou 2 quadros self.n = 1 # retornando n global para primeiro quadro if octeto.uint is Signal.FAS.value: # Comparação do FAS self.logger.info("FAS confirmado, PAQ Encontrado!") self.logger.debug("Buffer = %s" % self.buffer_frame.bin) self.state = State.ALIGNED # Transição de Estado self._print_state() self._get_information() #limpando buffers self.buffer_copy.clear() self.buffer_frame.clear() else: self.logger.info("FAS não confirmado, PAQ Inválido!") self.state = State.REALIGNING # Transição de Estado self.buffer_copy.clear() self.buffer_copy = self.buffer_frame.copy() self.logger.debug("Buffer Copy= %s" % self.buffer_copy.bin) self.buffer_frame.clear() self._print_state() self.logger.info("Procurando FAS...") # Estado de Alinhamento elif self.state is State.ALIGNED: frame, octeto = self._go_to_frame(2, buffer_bit) # Avançar 2 quadros if frame == 2: # Avançou 2 quadros if octeto.uint is Signal.FAS.value: # Comparação do FAS self.logger.info("FAS confirmado, PAQ Encontrado!") self._get_information() self.state = State.ALIGNED # Transição de Estado self.buffer_copy.clear() self.buffer_frame.clear() else: self.logger.info("FAS não confirmado, PAQ Inválido!") self.state = State.LOSS_ALIGNMENT_CHECK # Transição de Estado self._print_state() self.logger.info("Verificando perda do Alinhamento...") self.logger.info("Procurando FAS...") self.n = 4 # Estado de confirmação de perda do Alinhamento elif self.state is State.LOSS_ALIGNMENT_CHECK: frame, octeto = self._go_to_frame(self.n, buffer_bit) # Avançar 2 quadros if octeto: # Avançou quadros if octeto.uint is Signal.FAS.value: # Comparação do FAS self.logger.info("FAS confirmado, PAQ Encontrado!") self.logger.info("Alinhamento recuperado!") self.state = State.ALIGNED # Transição de Estado self._print_state() self._get_information() self.n = 1 # limpando buffers self.buffer_copy.clear() self.buffer_frame.clear() else: if frame == 4: # Avançou 4 quadros self.logger.info("FAS não confirmado, PAQ Inválido!") self.state = State.LOSS_ALIGNMENT_CHECK # Transição de Estado self.logger.info("Procurando FAS...") self.n = 6 elif frame == 6: # Avançou 6 quadros self.logger.info("FAS não confirmado, PAQ Inválido!") self.logger.info("Perda do alinhamento confirmada!") self.state = State.REALIGNING # Transição de Estado self.buffer_copy.clear() self.buffer_frame.clear() self._print_state() self.logger.info("Procurando FAS...") self.n = 1 @staticmethod def char_to_bit(char_bit: str) -> bin: """Função para converter um caractere em um bit Args: char_bit (str): caractere recebido para conversão Returns: bin: bit convertido """ if str(char_bit) == "0": return '0b0' elif str(char_bit) == "1": return '0b1' else: print("Error char = %s" % char_bit) def _go_to_frame(self, n_frame: int, buffer_bit: bin) -> [int, BitArray]: """Método privado responsável por avançar quadros Args: n_frame (int): número de quadros para avançar buffer_bit (bin): bit para adicionar ao buffer Returns: int,BitArray: int --> número de quadros avançados BitArray --> octeto com NFAS ou FAS para comparação """ self.buffer_frame.append( buffer_bit) # Avançar bits até completar quadro len_frame = len(self.buffer_frame) if len_frame == (n_frame * 256): # Avançou n quadros if n_frame > 1: self.logger.info("Avançando 2 Quadros...") else: self.logger.info("Avançando 1 Quadro...") start_pos = len_frame - 8 # (256 - 8) nfas_or_fas = self.buffer_frame[ start_pos:] # recuperando NFAS ou FAS if n_frame == 1: self.logger.info("NFAS = %s" % nfas_or_fas.bin) else: self.logger.info("FAS = %s" % nfas_or_fas.bin) self.logger.debug("Buffer = %s" % self.buffer_frame.bin) return n_frame, nfas_or_fas return 0, None def _get_information(self): """Método privado responsável por imprimir na tela o conteúdo entre PAQs """ self.logger.info("Recuperando Informação...") end_pos_info = len(self.buffer_frame) - 8 #(512 - 8) information = self.buffer_frame[: end_pos_info].bin # remover informação sem PAQ text = "Informação entre PAQs\n" text += "----------------------------------------\n" text += "%s\n----------------------------------------" % information self.logger.info(text) self.logger.debug("Buffer = %s" % self.buffer_frame.bin) def _print_state(self): """Método para imprimir os estados atuais durante a execução da Máquina """ self.logger.info("========================================") self.logger.info("Estado = %s" % self.state.name) self.logger.info("========================================")