使用C和Python在终端中获取随机字符

时间:2016-12-31 06:36:04

标签: c linux

出于某种原因,当我打开一个文件并在Python和C中逐字节地读取它并尝试打印结果时,我会混入随机字符/数据。

例如,当我读取PNG图像的前8个字节时,如下例所示:

/* Test file reading and see if there's random data */

#include <stdio.h>
#include <stdlib.h>
#include <malloc.h>

#define PNG_BYTES_TO_CHECK 8 

int
main(void)
{
    char fname[] = "../images/2.png";

    FILE *fp = fopen(fname, "rb");
    if (fp == NULL) abort();

    char *buffer = (char *)malloc(PNG_BYTES_TO_CHECK);

    if (fread(buffer, 1, PNG_BYTES_TO_CHECK, fp) != PNG_BYTES_TO_CHECK)
        abort();

    unsigned i;
    for (i = 0; i < PNG_BYTES_TO_CHECK; ++i) printf("%x ", buffer[i]);
    printf("\n");

    free(buffer); fclose(fp);

    return 1;
}

我把这个垃圾带到stdout:

ffffff89 50 4e 47 d a 1a a

但是当我用十六进制编辑器打开文件时,字节非常好(它是一个有效的PNG签名):

enter image description here

关于可能导致这种情况的任何想法?我没有Python的例子,但我记得几天前我在字节级处理文件并打印内容时会遇到重复的mumbo jumbo。

1 个答案:

答案 0 :(得分:1)

png spec表示png文件应始终以字节137 80 78 71 13 10 26 10开头。有符号字节的最大值为127,这意味着第一个字节的值溢出并变为-119(如果这令人困惑,请查看the way negative numbers are represented)。然后,您将其打印为无符号十六进制整数。为此,签名字节将提升为整数。同样,由于表示负数的方式,值为-119的4字节整数具有以下二进制表示:11111111111111111111111110001001%x无符号十六进制值的格式说明符。因为它认为你给它的值是无符号的,所以它不会将该二进制解释为好像它被表示为负数。如果您将11111111111111111111111110001001转换为十六进制,那么您会看到它是ffffff89

tl;博士:文件没有任何问题。你只是忘了让你的字节无符号。