簡體   English   中英

通過fget /緩沖區字符串解碼二進制文件(嘗試獲取mp3標頭)

[英]Decoding Binary via fget / buffer string (Trying to get mp3 header)

我正在編寫一些快速代碼,以嘗試從mp3文件頭中提取數據。

目的是從標頭中提取信息,例如比特率和其他重要信息,以便我可以使用必要的參數將文件適當地流式傳輸到mp3decoder。

這是顯示mp3header信息的Wikipedia圖像: http : //upload.wikimedia.org/wikipedia/commons/0/01/Mp3filestructure.svg

我的問題是,我是否正確地對此進行了攻擊? 打印接收到的數據毫無價值-我只是得到一堆隨機字符。 我需要獲取二進制文件,以便可以對其進行解碼並確定重要信息。

這是我的基准代碼:

// mp3 Header File IO.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"
#include "stdio.h"
#include "string.h"
#include "stdlib.h"

// Main function
int main (void)
{
    // Declare variables
    FILE *mp3file;
    char *mp3syncword; // we will need to allocate memory to this!!
    char requestedFile[255] = "";
    unsigned long fileLength;

    // Counters
    int i;

    // Memory allocation with malloc
    mp3syncword=(char *)malloc(2000);

    // Let's get the name of the requested file (hard-coded for now)
    strcpy(requestedFile,"testmp3.mp3");

    // Open the file with mode read, binary
    mp3file = fopen(requestedFile, "rb"); 
    if (!mp3file){
         // If we can't find the file, notify the user of the problem
         printf("Not found!");
    }

    // Let's get some header data from the file
    fseek(mp3file,1,SEEK_SET);
    fread(mp3syncword,32,1,mp3file);

    // For debug purposes, lets print the received data
     for(i = 0; i < 32; ++i)
        printf("%c", ((char *)mp3syncword)[i]);
    enter code here
    return 0;
}

幫助表示贊賞。

您正在使用%c作為格式說明符來打印字節。 您需要使用無符號數字格式說明符(例如, %u代表十進制數字, %x%X代表十六進制)來打印字節值。

您還應該將字節數組聲明為unsigned char因為它們在Windows上是默認簽名的。

您可能還希望在每個字節值之后打印一個空格(或其他分隔符),以使輸出更清晰。

標准printf不提供二進制表示類型說明符。 某些實現確實具有此功能,但Visual Studio隨附的版本則沒有。 為了輸出此信息,您將需要對數字執行位運算以提取單個位並針對每個字節依次打印每個位。 例如:

unsigned char byte = // Read from file
unsigned char mask = 1; // Bit mask
unsigned char bits[8];

// Extract the bits
for (int i = 0; i < 8; i++) {
    // Mask each bit in the byte and store it
    bits[i] = (byte & (mask << i)) >> i;
}

// The bits array now contains eight 1 or 0 values
// bits[0] contains the least significant bit
// bits[7] contains the most significant bit

C沒有以二進制形式打印的printf()說明符。 多數人改為以十六進制打印,這一次(通常)會給您八位:

printf("the first eight bits are %02x\n", (unsigned char) mp3syncword[0]);

您將需要手動解釋以找出各個位的值。 如果參數為負,則將其強制轉換為unsigned char以避免意外。

要測試位,可以將&運算符與按位左移運算符<<一起使用:

if(mp3syncword[2] & (1 << 2))
{
  /* The third bit from the right of the third byte was set. */
}

如果您希望對位使用“大”(大於7)索引,即將數據視為32位字,則最好將其讀入例如unsigned int ,然后進行檢查。 但是,在閱讀本文時,請注意字節序。

警告 :這種方法的內存布局和/或字節序可能存在錯誤。 不能保證結構成員在計算機之間匹配相同的位。
簡而言之:不要依賴於此(我會留下答案,這可能對其他事情很有用)

您可以使用位字段定義結構:

struct MP3Header {
    unsigned SyncWord : 12;
    unsigned Version : 1;
    unsigned Layer : 2;
    unsigned ErrorProtection : 1;
    unsigned BitRate : 4;
    unsigned Frequency : 2;
    unsigned PadBit : 1;
    unsigned PrivBit : 1;
    unsigned Mode : 2;
    unsigned ModeExtension : 2;
    unsigned Copy : 1;
    unsigned Original : 1;
    unsigned Emphasis : 2;
};

然后將每個成員用作隔離值:

struct MP3Header h;
/* ... */
fread(&h, sizeof h, 1, mp3file); /* error check!! */
printf("Frequency: %u\n", h.Frequency);

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM