“不可压缩”的数据序列

时间:2012-02-07 22:55:01

标签: networking compression vpn data-compression

我想通过算法生成X MBytes的“不可压缩”数据序列。我想这样做是为了创建一个通过VPN连接测量网络速度的程序(避免vpn内置压缩)。

任何人都可以帮助我吗?谢谢!

PS。我需要一个算法,我已经使用压缩到无法压缩的点的文件,但现在我需要以编程方式从头开始生成数据序列。

8 个答案:

答案 0 :(得分:8)

白噪声数据是真正随机的,因此是不可压缩的。

因此,您应该找到生成它的算法(或近似值)。

在Linux中试试这个:

# dd if=/dev/urandom bs=1024 count=10000 2>/dev/null | bzip2 -9 -c -v > /dev/null
(stdin): 0.996:1, 8.035 bits/byte, -0.44% saved, 10240000 in, 10285383 out.

你可以尝试任何类型的随机数生成......

答案 1 :(得分:5)

创建统计上难以压缩的数据的一种简单方法就是使用随机数生成器。如果您需要它可重复,请修复种子。任何相当不错的随机数发生器都可以。具有讽刺意味的是,如果您知道随机数生成器,结果是难以置信可压缩:唯一存在的信息是种子。但是,它会击败任何真正的压缩方法。

答案 2 :(得分:3)

您有几个选择:  1.使用一个像样的伪随机数发生器  2.使用AES之类的加密功能(随处可见的实现)

ALGO

  1. 想出你想要的任何钥匙。全零都很好。
  2. 创建一个空块
  3. 使用密钥
  4. 加密块
  5. 输出块
  6. 如果您需要更多数据,请转到3
  7. 如果操作正确,您生成的数据流将在数学上与随机噪声无法区分。

答案 3 :(得分:3)

其他答案指出随机噪声是不可压缩的,良好的加密函数的输出尽可能接近随机噪声(除非您知道解密密钥)。因此,一个好方法可能是使用随机数生成器或加密算法来生成不可压缩数据。

真正不可压缩(通过任何压缩算法)存在位串(对于“不可压缩”的某些形式定义),但即使识别它们在计算上也是不可判定的,更不用说生成它们了。

值得指出的是,“随机数据”只是不可压缩的,因为没有压缩算法能够在所有可能的随机数据上实现平均<1> 1 的压缩比。但是,对于任何特定随机生成的字符串,可能存在 实现良好压缩比的特定压缩算法。毕竟,任何可压缩的字符串都应该可以从随机生成器输出,包括像全零一样的愚蠢的东西,但不太可能。

因此,虽然从随机数生成器或加密算法中获取“可压缩”数据的可能性可能很小,但我希望在使用之前实际测试数据。如果您可以访问VPN连接中使用的最佳压缩算法;只是随机生成数据,直到你得到一些不会压缩的东西。否则,只需通过一些常用的压缩工具运行它并检查大小是否会减小就足够了。

答案 4 :(得分:2)

以下程序(C / POSIX)快速生成不可压缩数据,应该在每秒千兆字节范围内。我确信可以使用一般的想法使其更快(可能使用带有SIMD的Djb ChaCha核心?)。

/* public domain, 2013 */

#include <stdint.h>
#include <stdlib.h>
#include <unistd.h>
#include <time.h>

#define R(a,b) (((a) << (b)) | ((a) >> (32 - (b))))
static void salsa_scrambler(uint32_t out[16], uint32_t x[16])
{
    int i;
    /* This is a quickly mutilated Salsa20 of only 1 round */
    x[ 4] ^= R(x[ 0] + x[12],  7);
    x[ 8] ^= R(x[ 4] + x[ 0],  9);
    x[12] ^= R(x[ 8] + x[ 4], 13);
    x[ 0] ^= R(x[12] + x[ 8], 18);
    x[ 9] ^= R(x[ 5] + x[ 1],  7);
    x[13] ^= R(x[ 9] + x[ 5],  9);
    x[ 1] ^= R(x[13] + x[ 9], 13);
    x[ 5] ^= R(x[ 1] + x[13], 18);
    x[14] ^= R(x[10] + x[ 6],  7);
    x[ 2] ^= R(x[14] + x[10],  9);
    x[ 6] ^= R(x[ 2] + x[14], 13);
    x[10] ^= R(x[ 6] + x[ 2], 18);
    x[ 3] ^= R(x[15] + x[11],  7);
    x[ 7] ^= R(x[ 3] + x[15],  9);
    x[11] ^= R(x[ 7] + x[ 3], 13);
    x[15] ^= R(x[11] + x[ 7], 18);
    for (i = 0; i < 16; ++i)
        out[i] = x[i];
}

#define CHUNK 2048

int main(void)
{
    uint32_t bufA[CHUNK];
    uint32_t bufB[CHUNK];
    uint32_t *input = bufA, *output = bufB;
    int i;

    /* Initialize seed */
    srand(time(NULL));
    for (i = 0; i < CHUNK; i++)
        input[i] = rand();

    while (1) {
        for (i = 0; i < CHUNK/16; i++) {
            salsa_scrambler(output + 16*i, input + 16*i);
        }
        write(1, output, sizeof(bufA));

        {
            uint32_t *tmp = output;
            output = input;
            input = tmp;
        }
    }
    return 0;
}

答案 5 :(得分:0)

对于喜欢复制粘贴的人,这里有一些C#代码来生成包含(几乎)不可压缩内容的文件。代码的核心是MD5哈希算法,但是任何加密能力强(最终结果中具有良好的随机分布)的哈希算法都可以完成此工作(SHA1,SHA256等)。

它仅使用文件号字节(我的计算机中为32位小端序有符号整数)作为哈希函数的初始输入,并重新组合和连接输出,直到达到所需的文件大小为止。因此,对于待测压缩算法,文件内容是确定性的(相同的数字总是产生相同的输出)随机分布的“垃圾”。

    using System;
    using System.IO;
    using System.Linq;
    using System.Security.Cryptography;

    class Program {
    static void Main( string [ ] args ) {

        GenerateUncompressableTestFiles(
            outputDirectory  : Path.GetFullPath( "." ),
            fileNameTemplate : "test-file-{0}.dat", 
            fileCount        : 10,
            fileSizeAsBytes  : 16 * 1024
        );

        byte[] bytes = GetIncompressibleBuffer( 16 * 1024 );

    }//Main

    static void GenerateUncompressableTestFiles( string outputDirectory, string  fileNameTemplate, int fileCount, int fileSizeAsBytes ) {

       using ( var md5 = MD5.Create() ) {

          for ( int number = 1; number <= fileCount; number++ ) {

              using ( var content = new MemoryStream() ) {

                    var inputBytes = BitConverter.GetBytes( number );

                    while ( content.Length <= fileSizeAsBytes ) {

                        var hashBytes = md5.ComputeHash( inputBytes );
                        content.Write( hashBytes );
                        inputBytes = hashBytes;

                        if ( content.Length >= fileSizeAsBytes ) {
                            var file = Path.Combine( outputDirectory, String.Format( fileNameTemplate, number ) );
                            File.WriteAllBytes( file, content.ToArray().Take( fileSizeAsBytes ).ToArray() );
                        }

                    }//while

               }//using

            }//for

       }//using

    }//GenerateUncompressableTestFiles

    public static byte[] GetIncompressibleBuffer( int size, int seed = 0 ) { 

       using ( var md5 = MD5.Create() ) {

            using ( var content = new MemoryStream() ) {

                var inputBytes = BitConverter.GetBytes( seed );

                while ( content.Length <= size ) {

                    var hashBytes = md5.ComputeHash( inputBytes );
                    content.Write( hashBytes );
                    inputBytes = hashBytes;

                    if ( content.Length >= size ) {
                        return content.ToArray().Take( size ).ToArray();
                    }

                }//while

            }//using

        }//using

        return Array.Empty<byte>();

    }//GetIncompressibleBuffer 


    }//class

答案 6 :(得分:-1)

我刚刚创建了一个(非常简单且未经优化)的C#控制台应用程序,它可以创建不可压缩的文件。 它扫描文件夹中的文本文件(扩展名.txt),并为每个文本文件创建一个具有相同名称和大小的二进制文件(扩展名.bin)。 希望这有助于某人。 这是C#代码:

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
            var files = Directory.EnumerateFiles(@"d:\MyPath\To\TextFile\", "*.txt");
            var random = new Random();
            foreach (var fileName in files)
            {
                var fileInfo = new FileInfo(fileName);
                var newFileName = Path.GetDirectoryName(fileName) + @"\" + Path.GetFileNameWithoutExtension(fileName) + ".bin";
                using (var f = File.Create(newFileName))
                {
                    long bytesWritten = 0;
                    while (bytesWritten < fileInfo.Length)
                    {
                        f.WriteByte((byte)random.Next());
                        bytesWritten++;
                    }
                    f.Close();
                }
            }
        }
    }
}

答案 7 :(得分:-1)

一个非常简单的解决方案是生成随机字符串然后压缩它。 已压缩的文件是不可压缩的。