def generate_number(string): """ converts a string represenation of a combinator into its number :: # vector#1cb5c415 {t:Type} # [ t ] = Vector t generate_number('vector type:t # [ t ] = Vector') -> 0x1cb5c415 """ return int_c(crc32(string.encode()))
def encoded_combinator_number(data): """ converts a string represenation of a combinator into a bytes represenation of its number :: # vector#1cb5c415 {t:Type} # [ t ] = Vector t encoded_combinator_number('vector type:t # [ t ] = Vector') -> b'\x15\xc4\xb5\x1c' """ if isinstance(data, str): data = data.encode() return crc32(data).to_bytes(4, 'little')
def new(cls, seq_no, mtproto_msg): payload = mtproto_msg.get_bytes() # print('payload:', payload) # print(to_hex(scheme.int32_c(len(payload) + 12).get_bytes())) header_and_payload = bytes().join([ scheme.int32_c(len(payload) + 12).get_bytes(), scheme.int32_c(seq_no).get_bytes(), payload ]) crc = scheme.int32_c(crc32(header_and_payload)).get_bytes() return cls(header_and_payload + crc)
def process_game(self, game): tmp = tempfile.mkdtemp() build_dir = os.path.join(tmp, 'build') dist = os.path.join(tmp, 'dist.zip') c = self.db.cursor() c.execute( 'SELECT revision, sha256, title FROM game WHERE id = ? ORDER BY revision DESC LIMIT 1', (game.uid, )) revision, prev_sha256, prev_title = c.fetchone() or (1, None, None) os.mkdir(build_dir) shutil.move(game.content_path, os.path.join(build_dir, 'content')) sha256 = create_torrentzip(game.uid, game.platform, build_dir, dist) outfile = os.path.join(DIST_DIR, f'{game.uid}.zip') shutil.move(dist, outfile) if prev_sha256: if prev_sha256 == sha256: pcolor('green', 'no change') return revision += 1 for r, _, f in os.walk(build_dir): for fname in f: path = os.path.join(r, fname) rel = os.path.relpath(path, build_dir).replace(os.path.sep, '/') crc = util.crc32(path) md5 = util.digest(path, hashlib.md5()) sha = util.digest(path, hashlib.sha1()) size = os.stat(path).st_size self.db.execute('INSERT INTO file VALUES (?,?,?,?,?,?)', (sha256, rel, size, crc, md5, sha)) short_sha = sha256.hex()[:6].upper() pcolor('green', f'[rev {revision}: {short_sha}]') if prev_title and prev_title != game.title: pcolor( 'yellow', f'Warning: {game.uid} has been renamed ({prev_title} -> {game.title})' ) try: self.db.execute('INSERT INTO game VALUES (?,?,?,?,?,?)', (game.uid, revision, sha256, game.title, game.platform, self.session)) except sqlite3.IntegrityError as e: pcolor('red', f'Error: {e} when storing {game.title}. Skipped.') return self.db.commit() shutil.rmtree(tmp) if revision == 1: self.cleanup_obsolete(game, sha256)
def read_packet(): global prev_val while True: # read until we hit the next 0x1A 0x1A sequence # if we hit the end of the buffer, return while True: #if ser.in_waiting > 0: val = ord(ser.read()) # else: # time.sleep(0.05) # if ser.in_waiting == 0: # return None # val = ord(ser.read()) if val == 0x53 and prev_val == 0x53: prev_val = 0 break prev_val = val content = bytearray() while True: val = ser.read() c = ord(val) if c == 0x40: escaped = ser.read() content.extend(escaped) elif c == 0x53: prev_val = 0x53 return None elif c == 0x45: prev_val = 0 break else: content.append(c) payload = content[:-4] print('recv', payload) expected_checksum = crc32(payload) checksum, = struct.unpack('<I', content[-4:]) if expected_checksum != checksum: return None packet = Packet() packet.ParseFromString(payload) return packet
def write_packet(p): with write_lock: global req_id req_id = req_id + 1 p.req_id = req_id size = p.ByteSize() buf = bytearray() buf.append(0x53) buf.append(0x53) payload = p.SerializeToString() content = payload + struct.pack('<I', crc32(payload)) buf.extend(escape_buf(content)) buf.append(0x45) print('writing', p, buf) ser.write(buf) ser.flush()
def crc_ok(self): return self.crc == crc32(self.data[:-4])
def send_message(self, message, prev_return=None): """发送消息""" message_type = "" data = {} err = "" try: send_message_start = time.time() message_type = message.get("type", "") data = message.get("data", {}) err = message.get("err", "") # 如果有上一次(广播相同数据)的返回 # 相同的包名和连接标志 # 而且是无加密或简单加密 # 可以跳过组包, 直接使用上一次的发送数据 if prev_return \ and self.pg_tag == prev_return["tag"] \ and (not self._crypt or self._simple): message_str = prev_return["message_str"] packed = 0 else: packed = 1 self.msg_log(message_type, data=data, err=err) # 序列化 + 加密 if self._crypt: assert self._key, "no aes key! ignore sending message..." random_bytes_length = \ util.crc32(self._package_name + message_type) % 31 + 1 message_str = \ chr(random_bytes_length) + \ util.random_bytes(random_bytes_length) + \ util.aes_encrypt_smart(self._key, self._dumps(message), self._iv) # 序列化 else: message_str = self._dumps(message) # 压缩 if self._compress: # 压缩跳过(长度): 首字节表示是否压缩: \0x00 未压缩 \x01 压缩了 if self._compress_skip_size > 0: if len(message_str) > self._compress_skip_size: message_str = "\x01" + self._compress(message_str) else: message_str = "\x00" + message_str # 正常压缩 else: message_str = self._compress(message_str) # 编码 if self._base64: message_str = util.base64_encode(message_str) try: self.write_message(message_str, binary=self._binary) self.send += 1 self.send_bytes += len(message_str) # 平均发送延迟 # Conn.total_send += 1 Conn.total_send_time += time.time() - send_message_start if Conn.total_send % 10000 == 0: logging.debug( "Conn: total-sent %d messages, avg:%.3fus", Conn.total_send, Conn.total_send_time * 1000000.0 / Conn.total_send ) except: logging.error("send to client error:\n%s", format_exc()) return {"message_str": message_str, "tag": self.pg_tag, "packed": packed} except: self.error( "Exception:\n%son sending message error: type:%r %s %s\n", format_exc(), message_type, "data:%r" % data if data else "", "err:%r" % err if err else "", )
data = '' if args.ecc: if args.ecc > 127: die('Can add at most 127 pieces of redundancy') log('Error correction: %d extra pieces (~%d%% redundancy)' % \ (args.ecc, 100 * args.ecc / (args.split + args.ecc))) info[5] = args.ecc << 1 | 1 pieces = ecc(pieces, args.split + args.ecc) elif args.ecc: die('You must also specify --split to use --ecc') size = len(data) + 24 hdr = MAGIC + ''.join(map(chr, info)) + struct.pack('!I', size) crc = crc32(hdr + data) hdr += struct.pack('!I', crc) log('') log('File: %s' % dst) log('Size: %dB' % size) log('CRC : 0x%08x' % crc) if pieces: file(dst, 'wb').write(hdr) for i, piece in enumerate(pieces, 1): size = len(piece) + 8 crc = crc32(piece) path = '%s.%d' % (dst, i) log('') log('File: %s' % path)
constructors = {} new_session_created_c = create_constructor( name='new_session_created_c', number=0x9ec20908, params=['first_msg_id', 'unique_id', 'server_salt'], param_types=[long_c, long_c, long_c], result_type=NewSession) class Message(TLType): constructors = {} message_c = create_constructor( name='message_c', number=crc32('message msg_id:long seqno:int bytes:int body:Object = Message'.encode()), params=['msg_id', 'seqno', 'bytes', 'body'], param_types=[long_c, int_c, int_c, TLType], result_type=Message) class MessageContainer(TLType): constructors = {} msg_container_c = create_constructor( name='msg_container_c', number=0x73f1f8dc, params=['messages'], param_types=[vector_c(message_c)], result_type=MessageContainer)
new_session_created_c = create_constructor( name='new_session_created_c', number=0x9ec20908, params=['first_msg_id', 'unique_id', 'server_salt'], param_types=[long_c, long_c, long_c], result_type=NewSession) class Message(TLType): constructors = {} message_c = create_constructor( name='message_c', number=crc32( 'message msg_id:long seqno:int bytes:int body:Object = Message'.encode( )), params=['msg_id', 'seqno', 'bytes', 'body'], param_types=[long_c, int_c, int_c, TLType], result_type=Message) class MessageContainer(TLType): constructors = {} msg_container_c = create_constructor(name='msg_container_c', number=0x73f1f8dc, params=['messages'], param_types=[vector_c(message_c)], result_type=MessageContainer)