Alguém teria algum bom editor hexa para indicar? Eu estou desenvolvendo uma aplicação em C que trabalha com arquivos binários e preciso de um bom editor para visualizar os arquivos gerados para fazer alguns testes.
Não sei se é “bom”. Eu normalmente uso um plugin do Notepad++ que permite editar arquivos em hexa. Entretanto, deve haver editores mais decentes e especializados.
Eu acabei de baixar o plugin pra notepad++ para trabalhar com arquivos em hexa, como eu procedo com a instalação?
No Bing, pegue o primeiro link da consulta “notepad++ hex plugin install”
http://www.hhdsoftware.com/free-hex-editor - Ideal para arquivos gigantes
http://www.softcircuits.com/cygnus/ - Mais simples
Já que estamos escovando bits aqui, para ver dados de um canal socket:
http://www.wireshark.org/
Obrigado entanglement e ViniGodoy
ViniGodoy interessante esse wireshark. Quando eu terminar minha aplicação atual eu estava pensando em fazer uma em C que utilizasse redes e daí o wireshark será util.
Já tô vendo umas coisa sobre ele no google. Obrigado
A propósito ViniGodoy, instalei o editor hdd e abri um arquivo binário para testes. Tem uma tabela que contém caracteres hexa e tem uma outra coluna à direita com caracteres estranhos. O que essa coluna à direita representa?
A representação ascii desses caracteres. Geralmente não vai fazer sentido mesmo, a menos que no meio do arquivo tenha um texto. Quando isso ocorrer, aí será bem útil.
Eu costumo sempre carregar para lá e para cá um programa (em C++ mesmo, cujos fontes até perdi - a data do executável que tenho é de 1997, mas acho que escrevi esse programa ainda antes) que faz um “dump” de arquivos binários. (Mais ou menos o que esse editor hexadecimal faz). Um exemplo da saída desse programa:
0000 CA FE BA BE 00 00 00 32 00 0D 0A 00 03 00 0A 07 .■.....2........
0010 00 0B 07 00 0C 01 00 06 3C 69 6E 69 74 3E 01 00 ........<init>..
0020 03 28 29 56 01 00 04 43 6F 64 65 01 00 0F 4C 69 .()V...Code...Li
0030 6E 65 4E 75 6D 62 65 72 54 61 62 6C 65 01 00 0A neNumberTable...
0040 53 6F 75 72 63 65 46 69 6C 65 01 00 0A 43 6F 6E SourceFile...Con
0050 74 61 2E 6A 61 76 61 0C 00 04 00 05 01 00 0D 43 ta.java........C
0060 6F 6E 74 61 43 6F 72 72 65 6E 74 65 01 00 05 43 ontaCorrente...C
0070 6F 6E 74 61 00 20 00 02 00 03 00 00 00 00 00 01 onta. ..........
0080 00 00 00 04 00 05 00 01 00 06 00 00 00 1D 00 01 ................
0090 00 01 00 00 00 05 2A B7 00 01 B1 00 00 00 01 00 ......*.........
00A0 07 00 00 00 06 00 01 00 00 00 2A 00 01 00 08 00 ..........*.....
00B0 00 00 02 00 09 .....
Isso é um “dump” de um arquivo .class. Note que todos os arquivos .class começam pelos bytes: CA FE BA BE - algo bem Schwarzeneggeriano: “café, babe!”
Fiz uma função para isso em java:
[code]
private static String toHex(int value, int size)
{
String hex = Integer.toHexString(value).toUpperCase();
while (hex.length() < size)
hex = "0" + hex;
return hex;
}
private static char shortToChar(short character, char nonPrintable)
{
return character < 0x20 ? nonPrintable : (char) character;
}
/**
* Mount a String containing all bytebuffer data in a dump format. The
* dump format below use 16 bytes per line and '.' as a non-printable.:
*
* <pre>
* [0000] 54 68 69 73 20 69 73 20 61 20 73 61 6D 70 6C 65 |This is a sample
* [0010] 20 64 75 6D 70 13 66 6F 72 6D 61 74 21 | dump.format!
* </pre>
*
* The <code>nonPrintable</code> replaces some non-printable characters,
* such as line feed. This can be seen between the words "dump format" in
* the sample.
*
* @param data The bytebuffer data to dump. Using this method will not
* affect the ByteBuffer position.
* @param bytesPerLine Number of bytes to print in one line.
* @param nonPrintable Character that will replace non-printable chars.
* @return The dump string.
* @see #getDumpString(ByteBuffer)
*/
public static String getDumpString(ByteBuffer data, int bytesPerLine,
char nonPrintable)
{
if (data == null || !data.hasRemaining())
return "";
int oldPosition = data.position();
StringBuilder result = new StringBuilder();
int line = 0;
while (data.hasRemaining())
{
StringBuilder hexPart = new StringBuilder(3 * bytesPerLine);
StringBuilder asciiPart = new StringBuilder(bytesPerLine);
int bytesWritten = 0;
result.append("[").append(toHex(line * bytesPerLine, 4)).append(
"] ");
while (data.hasRemaining() && bytesWritten < bytesPerLine)
{
short ch = getUnsignedByte(data);
hexPart.append(toHex(ch, 2)).append(" ");
asciiPart.append(shortToChar(ch, nonPrintable));
bytesWritten++;
}
while (bytesWritten++ < bytesPerLine)
hexPart.append(" ");
result.append(hexPart).append("|").append(asciiPart).append("\n");
line++;
}
data.position(oldPosition);
return result.toString();
}
/**
* Mount a String containing all bytebuffer data in a dump format. The dump
* format is just like the above:
*
* <pre>
* [0000] 54 68 69 73 20 69 73 20 61 20 73 61 6D 70 6C 65 |This is a sample
* [0010] 20 64 75 6D 70 13 66 6F 72 6D 61 74 21 | dump.format!
* </pre>
*
* This method uses 16 bytes per line and '·' to replace non-printable
* characters.
*
* @param data The bytebuffer data to dump. Using this method will not
* affect the ByteBuffer position.
* @return The dump string.
* @see #getDumpString(ByteBuffer, int, char)
*/
public static String getDumpString(ByteBuffer data)
{
return getDumpString(data, 16, '.');
}[/code]
No JDK da Sun existe uma classe - sun.misc.HexDumpEncoder - que faz mais ou menos isso que o ViniGodoy implementou, só que essa classe está bugada e não consegue imprimir direito buffers de bytes cujo comprimento não seja múltiplo de 16. Como essa é uma classe “interna” da Sun, ela não será corrigida a menos que alguém da Sun resolva corrigir isso.
Esse código acima está intencionalmente nojento pq foi otimizado.
Daria para faze-lo muito mais simples com o string.format, mas como usávamos para rastrear um protocolo com tempos de resposta realmente baixos, tivemos que otimiza-lo e fazer muitas coisas no braço.
Dois meses depois…
Estava fazendo uns exercícios de um livro de C que estou lendo (e já estou acabando…) e um deles é proposto a criação de algo parecido com o do entanglement e do Vinícius. Não está aquelas coisas, mas funciona
Segue o código (editado para refletir a funcionalidade explicada pelo entanglement na próxima página):
[code]/*
- File: hexdump.c
-
@author David Buzatto
*/
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define NUM_BYTES 16
void dump( FILE *file );
void printHeader( void );
void printLine( const int *chars, int offsetLabel, int until );
int main( int argc, char *argv[] ) {
if ( argc == 2 ) {
char *filename = argv[1];
FILE *file = fopen( filename, "rb" );
if ( file != NULL ) {
dump( file );
fclose( file );
return EXIT_SUCCESS;
} else {
fprintf( stderr, "hexdump didn't find \"%s\"", filename );
return EXIT_FAILURE;
}
} else {
fprintf( stderr, "Usage: hexdump filename" );
return EXIT_FAILURE;
}
}
void dump( FILE *file ) {
int contOffset = 0;
int cont = 0;
int ch;
int previousChars[NUM_BYTES];
int chars[NUM_BYTES];
bool starAlreadyPrinted = false;
printHeader();
while ( ( ch = getc( file ) ) != EOF ) {
if ( cont < NUM_BYTES ) {
chars[cont] = ch;
cont++;
} else {
int equal = memcmp( chars, previousChars, sizeof( int ) * NUM_BYTES );
if ( equal == 0 ) {
if ( !starAlreadyPrinted ) {
printf( "*\n" );
starAlreadyPrinted = true;
}
} else {
printLine( chars, contOffset, NUM_BYTES );
starAlreadyPrinted = false;
}
memcpy( previousChars, chars, sizeof( int ) * NUM_BYTES );
chars[0] = ch;
cont = 1;
contOffset += NUM_BYTES;
}
}
printLine( chars, contOffset, cont );
}
void printHeader( void ) {
int i;
printf( "Offset " );
int total = NUM_BYTES * 3 - 4;
for ( i = 0; i < total / 2; i++ ) {
printf( " " );
}
printf( "Bytes" );
for ( ; i < total; i++ ) {
printf( " " );
}
printf( "Characters\n" );
printf( "------ " );
for ( i = 0; i < NUM_BYTES - 1; i++ ) {
printf( "---" );
}
printf( "-- " );
for ( i = 0; i < NUM_BYTES; i++ ) {
printf( "-" );
}
printf ( "\n" );
}
void printLine( const int *chars, int offsetLabel, int until ) {
int i;
printf( "%06X ", offsetLabel );
for ( i = 0; i < until; i++ ) {
printf( "%02X ", chars[i] );
}
for ( i = until; i < NUM_BYTES; i++ ) {
printf( " " ) ;
}
printf( " " );
for ( i = 0; i < until; i++ ) {
printf( "%c", isprint( chars[i] ) ? chars[i] : '.' );
}
printf( "\n" );
}[/code]
Ei davidbuzatto obrigado pelo fonte, funcionou igual aos editores citados pelos colegas.
David, esqueci de mencionar que há uma coisa que os programas que efetuam dumps binários costumam fazer também.
Quando há várias linhas repetidas (isso é muito comum em arquivos binários cheios de zeros binários) então as linhas são omitidaa e em seu lugar aparece uma estrela, assim:
0000 D0 CF 11 E0 A1 B1 1A E1 00 00 00 00 00 00 00 00 ................
0010 00 00 00 00 00 00 00 00 3E 00 03 00 FE FF 09 00 ........>...■...
0020 06 00 00 00 00 00 00 00 00 00 00 00 01 00 00 00 ................
0030 01 00 00 00 00 00 00 00 00 10 00 00 02 00 00 00 ................
0040 01 00 00 00 FE FF FF FF 00 00 00 00 00 00 00 00 ....■...........
0050 FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF ................
*
0200 FD FF FF FF FE FF FF FF FE FF FF FF FE FF FF FF ²...■...■...■...
0210 FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF ................
*
0400 52 00 6F 00 6F 00 74 00 20 00 45 00 6E 00 74 00 R.o.o.t. .E.n.t.
0410 72 00 79 00 00 00 00 00 00 00 00 00 00 00 00 00 r.y.............
0420 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
*
0440 16 00 05 00 FF FF FF FF FF FF FF FF 01 00 00 00 ................
0450 61 F9 56 88 0A 34 D0 11 A9 6B 00 C0 4F D7 05 A2 a.V..4...k..O...
0460 00 00 00 00 00 00 00 00 00 00 00 00 30 76 B3 89 ............0v..
0470 E1 9A CB 01 03 00 00 00 C0 00 00 00 00 00 00 00 ................
0480 43 00 4F 00 4E 00 54 00 45 00 4E 00 54 00 53 00 C.O.N.T.E.N.T.S.
0490 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
*
04C0 12 00 02 01 FF FF FF FF FF FF FF FF FF FF FF FF ................
04D0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
*
04F0 00 00 00 00 00 00 00 00 9C 00 00 00 00 00 00 00 ................
No exemplo acima, as linhas 0060, 0070… até 01F0 contém o mesmo valor que a linha 0050 (um monte de FF).
Oi entanglement. Não sabia desse detalhe!
Acabei de corrigir e programa para fazer da forma que você explicou.
Muito obrigado!
[]´s
Exemplo.
Entrada:asiudyuaisydas
asasasasasasas
asasasasasasas
xxxxxxxxxxxxxx
xxxxxxxxxxxxxx
xxxxxxxxxxxxxx
xxxxxxxxxxxxxx
bbbbbbbccccccc
bbbbbbbccccccc
bbbbbbbccccccc
ashdhsgdhasgdj
asdasdasddasds
asdasdasdsd
Saída:[code]Offset Bytes Characters
000000 61 73 69 75 64 79 75 61 69 73 79 64 61 73 0D 0A asiudyuaisydas…
000010 61 73 61 73 61 73 61 73 61 73 61 73 61 73 0D 0A asasasasasasas…
*
000030 78 78 78 78 78 78 78 78 78 78 78 78 78 78 0D 0A xxxxxxxxxxxxxx…
*
000070 62 62 62 62 62 62 62 63 63 63 63 63 63 63 0D 0A bbbbbbbccccccc…
*
0000A0 61 73 68 64 68 73 67 64 68 61 73 67 64 6A 0D 0A ashdhsgdhasgdj…
0000B0 61 73 64 61 73 64 61 73 64 64 61 73 64 73 0D 0A asdasdasddasds…
0000C0 61 73 64 61 73 64 61 73 64 73 64 asdasdasdsd[/code]
entanglement, essa separação de dois espaços entre os oito primeiros e oito últimos bytes é comum tbm? Fica mais fácil de visualizar.
Sr David Buzatto,
poderia entrar em contato,
desejo um programa em C para ler balanças eletronica. Uma toledo modalidade 9091.
obrigado
abrilsul@ig.com.br
Mineiro