Mostrando postagens com marcador Hexadecimal. Mostrar todas as postagens
Mostrando postagens com marcador Hexadecimal. Mostrar todas as postagens

segunda-feira, 20 de abril de 2015

EXPLORANDO UM POUCO MAIS A MANIPULAÇÃO DE STRINGS

Oi pessoas.
Me desculpem pelo hiato, mas é que as provas chegaram aí, já viram, né?

Pois bem, enquanto eu não consigo chegar no Salão do Tempo pra estudar um ano inteiro em um dia, vou fazendo o possível pra manter o blog atualizado.


Então... que tal brincar mais um pouquinho com strings???

Já aprendemos a inverter a string utilizando o [::-1] e também aprendemos a inverter a string de hexa com a biblioteca binascii.
Agora ensinarei aqui a inverter a string hexa sem transformar os dados, ou seja, trabalharemos diretamente com strings o tempo todo.

Supondo que a string seja:
'4b494b4f48c394' 
Que traduzindo de HEX para ASCII significa "KIKOHÔ".
Vamos inverter para que o resultado seja:
'94c3484f4b494b'  ou seja "ÔHOKIK".

>>> a='4b494b4f48c394'
>>> b=''
>>> for i in range(len(a),0,-2):    b=b+a[i-2:i]
>>> b
'94c3484f4b494b'

Muito bom, né?

O que isso quer dizer?

Muito bem. O for todo mundo conhece né? Não?
Então aqui vai:

for i in range(100):    .......

Isso quer dizer que 'i' irá receber os números de 0 a 99, pois irá fazer 100 iterações.

for i in range (1,100,1):    ........

Isso quer dizer que 'i' irá receber valores de 1 a 100 com passos de 1 em 1.

for i in range (1,100,2):    ........

Isso quer dizer que 'i' irá receber os valores de 1 a 100 com passos de 2 em dois, ou seja: 1,3,5,7,...,97,99.

Então voltando ao exemplo:

for i in range(len(a),0,-2):    b=b+a[i-2:i]

len(a) é o tamanho da string. No nosso caso 4b494b4f48c394 tem 14 caracteres, então len(a) = 14, daí o range NESSE CASO é: range(14,0,-2), então i recebe valores de 14 a 0 com passos de -2 (2 decrescente).

Aí vemos as instruções: b=b+a[i-2:i]. 

Na primeira iteração b está vazio (''), mas receberá a concatenação da string b ('') e do fragmento de string a[i-2:i], como o valor de 'i' na primeira iteração é 14, então será a[14-2:14] ou a[12:14]='94'. Ao fim dessa iteração b='94'

Na primeira iteração b contém ('94'), mas receberá a concatenação da string b ('94') e do fragmento de string a[i-2:i], como o valor de 'i' na segunda iteração é 12, então será a[12-2:12] ou a[10:12]='c3'. Ao fim dessa iteração b='94c3'.
E aí vai até que o range chegue a 0, percorrendo toda a string em a.
Por hoje é só, pessoal!

domingo, 12 de abril de 2015

BRINCANDO COM STRINGS - ÍNDICES E INVERSÕES


Vamos agora fazer umas 'falcatruas' com strings.

Escolhi strings por serem o resultado de muitas conversões

Vamos ao princípio básico: o índice.

>>> a='KAKAROTO'
>>> a[0]
'K'
>>> a[1]
'A'
>>> a[2]
'K'
>>> a[3]
'A'
>>> a[4]
'R'
>>> a[5]
'O'
>>> a[6]
'T'
>>> a[7]
'O'
>>> a[8]
Traceback (most recent call last):
  File "<pyshell#103>", line 1, in <module>
    a[8]
IndexError: string index out of range

Percebemos aqui então que o índice sempre começa com 0 (zero) e termina com o tamanho (lenth) -1. Ou seja, tem 8 caracteres de 0 a 7.

Aqui os escolhemos todos os índices do início [0] até [2]
>>> a[:2]
'KA'
Aqui escolhemos todos os índices maiores que dois até o fim na string
>>> a[2:]

'KAROTO'
Aqui escolhemos os quatro último índices.
>>> a[-4:]
'ROTO'
Aqui escolhemos todos os índices do início até o quarto último.
>>> a[:-4]
'KAKA'
Aqui escolhemos todos os índices, do primeiro [0] até o índice do tamanho total da string [len(a)]. O resultado é mesmo que se não especificássemos os índices, mas é de cunho didático.
>>> a[0:len(a)]

'KAKAROTO'
Aqui escolhemos do terceiro índice o tamanho total da string menos dois (total-2).
>>> a[3:len(a)-2]
'ARO'
Para entender direitinho  essa coisa de índice, veja a imagem lá em cima, ok?

Mas e se eu receber a string invertida???
Aí tem esse comando:

>>> b='ATEGEV'
>>> b[::-1]

'VEGETA'



Nossa! Que máximo!!! Ficou fácil inverter, hein? 
ÔPA! Péraí caceta! Fui inverter minha string de um resultado em HEX, deu errado!

Não se desespere! Vamos ver:

>>> h = hex(2341522)
>>> h
'0x23ba92'
>>> h[::-1]
'29ab32x0'

Realmente não deu muito certo. O que fazer?

Vamos lá.
Aqui utilizaremos uma biblioteca chamada binascii. Informações aqui e aqui.


>>> h= hex(2341522)
>>> h
'0x23ba92'
>>> h.split('x')[1]
'23ba92'
>>> h=h.split('x')[1]
>>> h
'23ba92'
>>> import binascii
>>> result=binascii.unhexlify(h[0:len(h)].encode())
>>> result
b'#\xba\x92'
>>> result[::-1]
b'\x92\xba#'
>>> result=binascii.unhexlify(h.encode())
>>> result
b'#\xba\x92'
>>> result=hexlify(result[::-1]).decode()
>>> result
'92ba23'

Vixxx Maria!!! Quanta informação!!!

Vamos com calma.
A parte do split, já vimos em um post anterior.
A parte do binascii.hexlify, transformou a string em um hexadecimal 'binário'. Daí, quando invertemos com o  [::-1], ao invés de inverter cada um dos caracteres, invertemos os bytes (conjuntos de oito bits).
A parte do binascii.unhexlify transfmormou o hexadecimal 'binário' em uma string novamente.
Tão lindo, não é?



sexta-feira, 10 de abril de 2015

CONVERSÕES ENTRE BASES: DECIMAL, HEXADECIMAL, INTEIRO, BINÁRIO E OCTAL

Bem... continuando com o assunto "conversões", vamos passar para as bases numéricas.

Se você está começando agora neste mundo de bases numéricas e ainda não pegou a "manha" da coisa, sugiro que leia estas dicas que lhe serão muito úteis no entendimento.

Pois bem. Vamos começar com o mais fácil: base decimal.

Atribuindo um valor decimal:

>>> inteiro = 65535
>>> inteiro
65535
>>> type(inteiro)
<class 'int'>

Transformando em hexadecimal (vimos no post anterior):

>>> hexadecimal = hex(inteiro)
>>> hexadecimal
'0xffff'
>>> type(hexadecimal)
<class 'str'>

Transformando em binário:

>>> binário = bin(inteiro)
>>> binário
'0b1111111111111111'
>>> type(binário)
<class 'str'>

Transformando em octal:

>>> octal=oct(inteiro)
>>> octal
'0o177777'
>>> type(octal)
<class 'str'>
_____________________________________________
Para os apressadinhos, vou adiantar que há uma maneira de transformar um número decimal em hexadecimal em que o resultado é em binário (bytes) e não uma string como o hex(inteiro), mas a explicação darei em outra oportunidade:

Primeiro, importamos a biblioteca struct, depois usamos-na para a conversão:

LITTLE ENDIAN (default):

>>>import struct
>>> struct.pack('<l',inteiro)
b'\xff\xff\x00\x00'

BIG ENDIAN:
>>> struct.pack('>l',inteiro)
b'\x00\x00\xff\xff'

Então temos:

>>> binhex=struct.pack('>l',inteiro)
>>> type(binhex)
<class 'bytes'>
>>> binhex
b'\x00\x00\xff\xff'
_____________________________________________

Vamos agora partir para o octal:

Transformando em inteiro:
>>> octal='0o177777'
>>> inteiro=int(octal,8)
>>> inteiro
65535
>>> type(inteiro)
<class 'int'>

Transformando em hexadecimal. Nesse caso, temos que dar uma "roubadinha":

>>> octal='0o177777'
>>> hexadecimal=int(octal,8)
>>> octal='0o177777'
>>> hexadecimal=hex(int(octal,8))
>>> hexadecimal
'0xffff'
>>> type(hexadecimal)
<class 'str'>

A mesma "roubadinha" para binário:

>>> octal='0o177777'
>>> binário=bin(int(octal,8))
>>> binário
'0b1111111111111111'
>>> type(binário)
<class 'str'>

E por último, vamos para o binário:

Transformando em inteiro:

>>> binário='0b1111111111111111'
>>> inteiro=int(binário,2)
>>> inteiro
65535
>>> type(inteiro)
<class 'int'>

Transformando em hexadecimal (roubandinha):

>>> hexadecimal=hex(int(binário,2))
>>> hexadecimal
'0xffff'
>>> type(hexadecimal)
<class 'str'>

Transformando em octal (roubadinha):

>>> octal=oct(int(binário,2))
>>> octal
'0o177777'
>>> type(octal)
<class 'str'>

quinta-feira, 9 de abril de 2015

CONVERSÕES INTEIRO - HEXADECIMAL - INTEIRO

O ruim do Python 3.x é que a maioria dos resultados é dado como uma string.
Então se você, por exemplo, atribui um inteiro à uma variável e converte para Hexadecimal, terá uma string como retorno.
Observe:

>>> inteiro=64
>>> type(inteiro)
<class 'int'>
>>> hexadecimal=hex(inteiro)
>>> type(hexadecimal)
<class 'str'>
>>> inteiro
64
>>> hexadecimal
'0x40'

Nada mal, você pensa, afinal os valores estão certos. Porém os tipos não estão. Isso à princípio não faz muita diferença. Mas quando você começar a manipular esses dados, vai ter problemas certamente.

Bem... chega de Lero-Lero.
Vamos a algumas transformações:

String em inteiro:

>>> a = 'ac6cad'
>>> int(a,16)
11300013

Inteiro em string:

>>> b=11300013
>>> b
11300013
>>> hex(b)
'0xac6cad'

Para tirar o '0x' da string:

>>> hex(b).split('x')[1]
'ac6cad'

'split' é para "fatiar" a string. o ('x') é o pondo onde você irá fatiar, neste caso. Portanto, se você fizer:

>>> hex(b).split('x')
['0', 'ac6cad']

então a primeira posição [0] contém '0' e a segunda posição [1] contém ['ac6cad'].


Bem... espero ter ajudado no começo....

Qualquer outro tipo de conversão hex-int ou int-hex necessário, por favor, deixem um comentário que terei prazer em incluir neste tópico.