首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >jpeg文件中的字节分布

jpeg文件中的字节分布
EN

Stack Overflow用户
提问于 2012-12-04 21:59:36
回答 3查看 791关注 0票数 4

在观察压缩数据时,我希望得到一个几乎均匀分布的字节流。当使用卡方检验来测量分布时,我得到了这个结果,例如对于ZIP文件和其他压缩数据,但对于JPG文件则不是。过去几天,我一直在寻找原因,但我找不到任何原因。

在计算JPG的熵时,我得到了很高的结果(例如7,95位/字节)。我认为熵和分布之间一定有联系:当每个字节以几乎相同的概率出现时,熵是高的。但是当使用卡方时,a得到一个p值,大约是4,5e-5…

我只是想了解不同的分布如何影响测试结果。我以为我可以用这两个测试来测量相同的属性,但显然我不能。

非常感谢您的任何提示!汤姆

EN

回答 3

Stack Overflow用户

发布于 2012-12-05 03:24:32

在jpeg文件中分发

忽略元信息和jpeg报头数据,jpeg的有效载荷由描述huffmann-tables或编码MCU的块(最小编码单元,大小为16×16的方形块)组成。可能还有其他的,但这是最常见的。

这些块由0xFF 0xSS分隔,其中0xSS是特定的起始码。这是第一个问题:正如twalberg在评论中提到的那样,0xFF的使用频率更高一些。

它可能发生,0xFF发生在编码MCU中。为了区分这个正常的有效负载和新块的开始,插入了0xFF 0x00。如果未填充有效载荷的分布是完全均匀的,则填充数据中的0x00频率将是填充数据的两倍。更糟糕的是,每个MCU都充满了二进制1,以获得字节对齐(稍微偏向于更大的值),我们可能需要再次填充。

可能还有其他一些我没有意识到的因素。如果您需要更多信息,您必须提供jpeg-file。

关于你的基本假设:

对于rand_data:

代码语言:javascript
复制
 dd if=/dev/urandom of=rand_data count=4096 bs=256

对于rand_pseudo (python):

代码语言:javascript
复制
s = "".join(chr(i) for i in range(256))
with file("rand_pseudo", "wb") as f:
    for i in range(4096):
        f.write(s)

两者在字节值方面应该是一致的,不是吗?;)

代码语言:javascript
复制
$ ll rand_*
-rw-r--r-- 1 apuch apuch 1048576 2012-12-04 20:11 rand_data
-rw-r--r-- 1 apuch apuch 1048967 2012-12-04 20:13 rand_data.tar.gz
-rw-r--r-- 1 apuch apuch 1048576 2012-12-04 20:14 rand_pseudo
-rw-r--r-- 1 apuch apuch    4538 2012-12-04 20:15 rand_pseudo.tar.gz

均匀分布可能表示较高的entropy,但这不是保证。此外,rand_data可能由1MB的0x00组成。这是极不可能的,但却是可能的。

票数 1
EN

Stack Overflow用户

发布于 2012-12-06 01:02:22

在这里你可以找到两个文件:第一个是随机数据,用dev/unrandom生成(大约46MB),第二个是一个普通的JPG文件(大约9MB)。很明显,JPG-file的符号并不像dev/urandom中那样均匀分布。

如果我比较这两个文件:

熵: JPG: 7,969247位/字节RND: 7,999996位/字节

卡方检验的p值: JPG: 0 RND: 0,3621

熵怎么会导致这么高的结果?!?

票数 0
EN

Stack Overflow用户

发布于 2014-03-09 16:59:55

下面是我的java代码

代码语言:javascript
复制
         public static double getShannonEntropy_Image(BufferedImage actualImage){
         List<String> values= new ArrayList<String>();
           int n = 0;
           Map<Integer, Integer> occ = new HashMap<>();
           for(int i=0;i<actualImage.getHeight();i++){
             for(int j=0;j<actualImage.getWidth();j++){
               int pixel = actualImage.getRGB(j, i);
               int alpha = (pixel >> 24) & 0xff;
               int red = (pixel >> 16) & 0xff;
               int green = (pixel >> 8) & 0xff;
               int blue = (pixel) & 0xff;
//0.2989 * R + 0.5870 * G + 0.1140 * B greyscale conversion
//System.out.println("i="+i+" j="+j+" argb: " + alpha + ", " + red + ", " + green + ", " + blue);
                int d= (int)Math.round(0.2989 * red + 0.5870 * green + 0.1140 * blue);
               if(!values.contains(String.valueOf(d)))
                   values.add(String.valueOf(d));
               if (occ.containsKey(d)) {
                   occ.put(d, occ.get(d) + 1);
              } else {
                  occ.put(d, 1);
              }
              ++n;
       }
    }
    double e = 0.0;
    for (Map.Entry<Integer, Integer> entry : occ.entrySet()) {
         int cx = entry.getKey();
         double p = (double) entry.getValue() / n;
         e += p * log2(p);
    }
 return -e;
  }
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/13704600

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档