Visualização de dados para análise de padrões (independente da linguagem, mas R preferida)

11

Quero plotar os bytes de uma imagem de disco para entender um padrão neles. Isso é principalmente uma tarefa acadêmica, pois tenho quase certeza de que esse padrão foi criado por um programa de teste de disco, mas eu gostaria de fazer a engenharia reversa de qualquer maneira.

Eu já sei que o padrão está alinhado, com uma periodicidade de 256 caracteres.

Posso visualizar duas maneiras de visualizar essas informações: um plano de 16x16 visualizado no tempo (3 dimensões), em que a cor de cada pixel é o código ASCII do personagem ou uma linha de 256 pixels para cada período (2 dimensões).

Este é um instantâneo do padrão (você pode ver mais de um), visto através xxd(32x16):

Padrão para analisar

De qualquer forma, estou tentando encontrar uma maneira de visualizar essas informações. Provavelmente, isso não é difícil para ninguém na análise de sinais, mas não consigo encontrar uma maneira de usar software de código aberto.

Gostaria de evitar o Matlab ou o Mathematica e preferiria uma resposta em R, já que tenho aprendido isso recentemente, mas mesmo assim qualquer idioma é bem-vindo.


Atualização, 25/07/2014: dada a resposta de Emre abaixo, é assim que o padrão se parece, dados os primeiros 30 MB do padrão, alinhados em 512 em vez de 256 (esse alinhamento parece melhor):

Padrão gráfico

Outras idéias são bem-vindas!

Valmiky Arquissandas
fonte
Um exemplo / trecho dos dados (talvez apenas alguns MB) pode ser interessante.
Marco13
Se você estiver interessado na natureza periódica dos dados, ver a DFT dos dados pode ser revelador.
22414 mrmcgreg
@mrmcgreg: terei que reaprender como o DFT funciona. Eu deveria ter prestado mais atenção aos sinais e sistemas de aulas :)
Valmiky Arquissandas

Respostas:

5

Eu usaria uma análise visual. Como você sabe que há uma repetição a cada 256 bytes, crie uma imagem com 256 pixels de largura por mais de profundidade e codifique os dados usando o brilho. Em (i) python, ficaria assim:

import os, numpy, matplotlib.pyplot as plt

%matplotlib inline

def read_in_chunks(infile, chunk_size=256):
    while True:
        chunk = infile.read(chunk_size)
        if chunk:
            yield chunk
        else:
            # The chunk was empty, which means we're at the end
            # of the file
            return

fname = 'enter something here'
srcfile = open(fname, 'rb')
height = 1 + os.path.getsize(fname)/256
data = numpy.zeros((height, 256), dtype=numpy.uint8)    

for i, line in enumerate(read_in_chunks(srcfile)):
    vals = list(map(int, line))
    data[i,:len(vals)] = vals

plt.imshow(data, aspect=1e-2);

É assim que um PDF se parece:

Um arquivo PDF visualizado

Um padrão periódico de 256 bytes se manifestaria como linhas verticais. Exceto pelo cabeçalho e cauda, ​​parece bastante barulhento.

Emre
fonte
Parece bastante com o que estou procurando. Estou estudando para as finais agora e não consigo dedicar um tempo para pensar sobre isso de novo, mas assim que puder, eu o informarei. "Um padrão periódico de 256 bytes se manifestaria como linhas verticais". - exatamente no que eu estava pensando. Também posso mostrar uma imagem em que coloquei todos os 256 bytes na mesma linha, e isso já é óbvio no texto. Estou muito curioso sobre o que vai sair dela :)
Valmiky Arquissandas
Não consigo rodar isso no Debian Linux. Eu instalei os pacotes python-scitoolse ipython. A mensagem de erro é ValueError: invalid literal for int() with base 10: '#'. Vou ver se eu posso fazê-lo funcionar de qualquer maneira ...
Valmiky Arquissandas
Consegui (executando o código diretamente dentro ipython, e mudar map(int, line)para map(ord, line), e atualizei a questão com a nova imagem.
Valmiky Arquissandas
Levei um ano, mas decidi aceitar esta resposta. Ainda não sei o que é esse fluxo de bits, mas provavelmente não vou descobrir. Mas tem um bom padrão!
Valmiky Arquissandas
1

Eu sei quase nada sobre análise de sinais, mas 2-dimensional visualização pode ser feito facilmente usando R. Particularmente você precisará reshape2e ggplot2pacotes. Supondo que seus dados sejam amplos (por exemplo, tamanho [n X 256]), primeiro você precisará transformá-los em formato longo usando a melt()função do reshape2pacote. Em seguida, use a geom_tilegeometria de ggplot2. Aqui está uma boa receita com essência .

sobach
fonte
2
São mais de 4 GB de dados. Eu deveria traçá-lo lendo stdin ou algo semelhante. É uma má idéia carregar tudo na RAM. Vou dar uma olhada no que você disse em alguns dias - e espero que outras idéias possam surgir - e informarei como foi, obrigado!
Valmiky Arquissandas
Não o carregue e trate como um quadro de dados, não é um quadro de dados, é um fluxo de bytes.
Spacedman
1

Eu examinaria o rasterpacote para isso, que pode ler dados binários brutos e apresentá-lo como grades NxM. Pode até extrair subconjuntos de grandes grades binárias sem ter que ler o arquivo inteiro (o próprio objeto rasterizado R é apenas um proxy para os dados, não para os próprios dados).

Spacedman
fonte