Camada Física da Computação - Aula 1 - exemplos de operações básicas
1) Nesta atividade você irá aprimorar seus conhecimentos em relação à representação dos dados que iremos transmitir. Seu primeiro passo será converter números na representação decimal em outras bases. Você conseguiria converter os números 12, 16, 34 e 255 para a base binária? Tente fazer a transformação.
2) Agora vamos fazer o inverso. Qual é o valor em decimal para o número b00010010 (a letr b indica que a representação está em base binária, na verdade um byte de 8 bits)
3) Podemos fazer estas transformações através de códigos. Utilize a função do python bin(numDec), que transforma um numero decimal em binário, e também a funcao int('numBin',2), que transforma o binario em decimal inteiro, e confira seus resultados ateriores!
4) Vamos agora considerar a base numérica de 16 símbolos, que chamamos de hexadecimal. Nesse caso, usamos "0x" antes de um número para indicar que está na base hexadecinal. Lembre-se da explicação do seu professor ou revise o material de aula se precisar e escreva os números 8, 15, 16 e 255 em base hexadecimal.
5) Verifique o codigo abaixo. A função bytes([]) do python para tranformar números decimais em hexadecimais e confira seu resultado.
print('respostas anteriores: 8={}, 15={}, 16={}, 255={}' .format(bytes([8]),bytes([15]),bytes([16]),bytes([255])))
print('ou ainda: respostas anteriores: 8={}' .format((8).to_bytes(2, byteorder='big')))
print('ou ainda: respostas anteriores: 8={}' .format((8).to_bytes(3, byteorder='little')))
print('ou ainda: respostas anteriores: 1024={}' .format((1024).to_bytes(5, byteorder='big')))
print('ou ainda: respostas anteriores: 1024={}' .format((1024).to_bytes(5, byteorder='little')))
6) Quantos bits seriam necessários para representar 0xFF em binário?
7) Agora vamos entender como um valor hexadecimal pode se convertido em um int. Para isso você deverá "printar" os valores abaixo e fazer algo investigativo! Tente descobrir como funciona a função "int.from_bytes", que tranforma vários bytes em um int.
valor1 = int.from_bytes(b'\x00\x1C', byteorder='little')
valor2 = int.from_bytes(b'\x00\x1C', byteorder='big')
valor3 = int.from_bytes(b'\x1C\x00', byteorder='little')
valor4 = int.from_bytes(b'\x00\x1A', byteorder='big', signed=True)
valor5 = int.from_bytes(b'\x7F\xFF', byteorder='big', signed=True)
valor6 = int.from_bytes(b'\x80\x00', byteorder='big', signed=True)
valor7 = int.from_bytes(b'\xAB\xC5', byteorder='big', signed=True)
valor8 = int.from_bytes(b'\xFF\xFF', byteorder='big', signed=True)
valor9 = int.from_bytes(b'\xFF\xFF\A3\67', byteorder='big')
print('valor1={} \n valor2={} \n valor3={} \n valor4={} \n valor5={} \n valor6={} \n valor7={} \n valor8={} \n valor9 {}' .format(valor1, valor2, valor3,valor4, valor5, valor6,valor7,valor8,valor9))
Repare que os parametros "little" e "big" definem a ordem de leitura dos bytes (esquerda para direita ou direita para esquerda). estamos acostumados a ter os digitos mais significativos na esquerda, então normalmente usamos o parâmetro "big".
O parâmetro "signed" quando "true" reparte os possíveis valores formados pelos n Bytes sendo convertidos em duas metades. A primeira sendo crescente e positiva. A segunda sendo o complemento e negativo. Por exemplo: se estamos falando de 2 bytes, temos 65536 possíveis valores. Se usamos "signed=False" os números irão de 0 a 65535. Se usarmos "signed=True" a conversão se dará naturalmente de 0 a 32768 e a partir de então, o valor torna-se negativo, como se fosse subtraido -65536 de cada conversão. Isso permite valores positivos e negativos de -32768 a + 32768.
8) Você deve ter percebido no item 7 que para cada 8 bits são necessários 2 dígitos do Hexadecimal. Ou seja, um byte! Muitas vezes quando queremos expressar o conteúdo de um byte de memória (8 bits) é conveniente expressá-lo em hexadecimal, sendo apenas 2 dígitos, por exemplo 0x6B. Agora vamos fazer uma lista de bytes! Há 2 maneiras! Você pode criar uma lista correspondente de decimais e fazendo algo como listaBytes.append(bytes(int)). Alternativamente, em caso de pequenas listas você pode escrever cada um dos bytes. Para escrever o byte A4, por exemplo, você deve escrever b'\xA4'. P Código abaixo implementa 3 diferentes listas de bytes. tente entender o que foi feito.
#seu código
#lista1 de 0x00 a 0x1F
#lista2 de 0x09 a 0x10
#lista3 de 0x20 a 0x7F
# solução lista 1
listaBytes=[]
for x in range(0,12):
listaBytes.append(bytes([x]))
print('lista1: {} ' .format(listaBytes))
#solução lista 2
listaBytes=[]
listaBytes=[b'\x09',b'\x0A',b'\x0B',b'\x0C',b'\x0D'b'\x0E'b'\x0F',b'\x10']
print(' \n lista2: {} ' .format(listaBytes))
#solução lista 3
listaBytes=[]
for x in range(int.from_bytes(b'\x30', byteorder='big'),int.from_bytes(b'\x3F', byteorder='big')):
listaBytes.append(bytes([x]))
print('\n lista3: {} ' .format(listaBytes))
lista4 = listaBytes + listaBytes
print('\n lista4: {} ' .format(listaBytes))
Você deve estar se perguntando sobre o porquê de vários caracteres terem aparecidos no print! Já ouviu a respeito de tabela ASCII, certo? É uma tabela que associa um caractere a um byte, possibilitando armazenar nossos textos em forma de bytes e também conver os bytes novamente para nosso idioma (não é qualquer um que lê em bytes). A função "print" do Python faz automaticamnete essa conversão de byte para caractere quando o byte a ser "printado" está entre 0x20 e 0x7F. Faça o teste com um print do byte, por exemplo, 0x4D. Esse byte, segundo a tabela (você pode encontrar a tabela ascii on line), é associado ao caractere "M". A função "print" sempre retornará o caractere associado ao seu respectivo byte quando este estiver entre 0x20 e 0x7F! Importante: Repare que esta associação vale para interface, ou seja, armazenar caracteres ou ler caracteres armazenados. Já quando queremos armazenar simplesmente um número em uma variável, por exemplo, 132, não precisamos armazenar um byte para cada caractere! Apenas precisamos de um único byte: 0x84 (equivale a 132)! A associação de 1 byte para cada caractere é apenas para nossa interface (prints e varíaveis contendo caracteres, como chars e strings).
Por fim, você também poderá usar bytes organizados em forma de "array", através do bytearray. Veja o exemplo abaixo.