바이너리 파일에서 바이트 발생에 대한 통계를 어떻게 수집할 수 있나요?

바이너리 파일에서 바이트 발생에 대한 통계를 어떻게 수집할 수 있나요?

나는

cat inputfile | sed 's/\(.\)/\1\n/g' | sort | uniq -c

에서 자랐다https://stackoverflow.com/questions/4174113/how-to-gather-characters-usage-statistics-in-text-file-using-unix-commands텍스트 파일에서 문자 사용 통계를 생성하는 데 사용됩니다. 바이너리 파일의 경우 문자 대신 단순 바이트가 계산됩니다. 즉, 출력은 다음 형식이어야 합니다.

18383 57
12543 44
11555 127
 8393 0

명령이 인용된 문자만큼 오래 걸리는지는 중요하지 않습니다.

바이너리 파일에 문자 명령을 적용하면 출력에는 인쇄할 수 없는 임의의 긴 문자 시퀀스에 대한 통계가 포함됩니다(이에 대한 설명은 찾고 있지 않습니다).

답변1

GNU 사용 od:

od -vtu1 -An -w1 my.file | sort -n | uniq -c

또는 보다 효율적으로 사용하려면 perl(또한 존재하지 않는 바이트의 출력 개수(0)):

perl -ne 'BEGIN{$/ = \4096};
          $c[$_]++ for unpack("C*");
          END{for ($i=0;$i<256;$i++) {
              printf "%3d: %d\n", $i, $c[$i]}}' my.file

답변2

대용량 파일의 경우 sort를 사용하면 속도가 느려질 수 있습니다. 나는 동등한 문제를 해결하기 위해 짧은 C 프로그램을 작성했습니다(테스트가 포함된 Makefile에 대한 이 요점을 참조하세요.):

#include <stdio.h>

#define BUFFERLEN 4096

int main(){
    // This program reads standard input and calculate frequencies of different
    // bytes and present the frequences for each byte value upon exit.
    //
    // Example:
    //
    //     $ echo "Hello world" | ./a.out
    //
    // Copyright (c) 2015 Björn Dahlgren
    // Open source: MIT License

    long long tot = 0; // long long guaranteed to be 64 bits i.e. 16 exabyte
    long long n[256]; // One byte == 8 bits => 256 unique bytes

    const int bufferlen = BUFFERLEN;
    char buffer[BUFFERLEN];
    int i;
    size_t nread;

    for (i=0; i<256; ++i)
        n[i] = 0;

    do {
        nread = fread(buffer, 1, bufferlen, stdin);
        for (i = 0; i < nread; ++i)
            ++n[(unsigned char)buffer[i]];
        tot += nread;
    } while (nread == bufferlen);
    // here you may want to inspect ferror of feof

    for (i=0; i<256; ++i){
        printf("%d ", i);
        printf("%f\n", n[i]/(float)tot);
    }
    return 0;
}

용법:

gcc main.c
cat my.file | ./a.out

답변3

평균, 시그마 및 CV는 바이너리 파일 내용의 통계를 판단하는 데 종종 중요하므로 이 모든 데이터를 시그마 바이트에서 벗어나는 ASCII 원으로 표시하는 cmdline 프로그램을 만들었습니다.
http://wp.me/p2FmmK-96
grep, xargs 등과 같은 도구와 함께 사용하여 통계를 추출할 수 있습니다. 여기에 이미지 설명을 입력하세요.

답변4

이것은 Stephane의 답변과 유사 od하지만 바이트의 ASCII 값을 표시합니다. 또한 빈도/발생 횟수별로 정렬됩니다.

xxd -c1 my.file|cut -c10-|sort|uniq -c|sort -nr

많은 프로세스가 시작되기 때문에 그다지 효율적이지 않다고 생각하지만 단일 파일, 특히 작은 파일에는 좋습니다.

관련 정보