13

I want to create an image file so it's exactly 5MB for testing purposes. Is it possible?

6
  • 29
    Why would you want to do this? (It may affect the answers.)
    – MikeB
    Commented Mar 25, 2020 at 9:58
  • 6
    @MikeBrockington I'm testing website security where upload limit is 5mb
    – John Doe
    Commented Mar 25, 2020 at 11:11
  • 14
    So do you really need a genuine image file for this, or just a 5mb bunch of zeroes, with a .jpeg file extension?
    – MikeB
    Commented Mar 25, 2020 at 14:19
  • 3
    I find the term image file very broad. You can copy a HDD to an .iso file. Wouldn't that be an image file, too? You mean a graphics file. Commented Mar 26, 2020 at 12:54
  • fallocate can create exact filesizes.
    – Raven
    Commented Mar 26, 2020 at 21:19

6 Answers 6

4

As suggested in the comments, you can use the image metadata. jpg supports exif data. You mentioned php, which can write raw exif data with iptcembed(). Generate a string of null bytes (binary 0) long enough to pad out the file

<?php
$path = '/path/to/image.jpg';
$size = filesize($path);
$goal = 1024 * 1024 * 5; //5MB
$zeros = str_pad("", $goal - $size, "\0"); // make a string of ($goal - $size) binary 0s
$paddedImage = iptcembed($zeros, $path);
file_put_contents("/path/to/padded-image.jpg", $paddedImage);
3
  • The idea of binary nuls is fine, but in reality any data after the end of the file is fine. One may even append multiple copies of the file to itself to reach the required size.
    – Criggie
    Commented Mar 25, 2020 at 18:20
  • 1
    @Criggie gotcha, I'm not as familiar with how trailing data is handled in images. In this case, since its writing exif data and not just trailing data, I like the binary nulls so you don't end up with corrupt exif data
    – chiliNUT
    Commented Mar 25, 2020 at 18:35
  • 1
    Case in point: rarjpeg. It's an image file spliced with a rar file, each program only reads its own part. Commented Mar 26, 2020 at 13:38
26

Most implementations of image formats ignore trailing zeros. Therefore, it is relatively straightforward to pad a file to a desired size. (5 megabytes is 10240 blocks.)

#! /usr/bin/env bash

print_usage_and_exit(){
  echo "Usage: $0 FILE BLOCKS"
  echo "This script will pad FILE with zeros up to BLOCKS."
  echo "FILE must not already be larger than BLOCKS."
  exit
}
FILE=$1
BLOCKS=$2
if [ -z $FILE ] || [ -z $BLOCKS ] || [ -z "${BLOCKS##*[!0-9]*}" ]; then
  print_usage_and_exit
fi
FILE_SIZE=$(stat $FILE | awk '/Blocks:/ { print $4 }')
SIZE_DIFFERENCE=$(($BLOCKS-$FILE_SIZE))
if [ $SIZE_DIFFERENCE -le 0 ]; then
  print_usage_and_exit
fi
dd if=/dev/zero iflag=append count=$SIZE_DIFFERENCE >> $FILE 2>/dev/null
10
  • 13
    Some image formats also have metadata areas, in which I assume data can also be added to pad out the size
    – Keltari
    Commented Mar 25, 2020 at 2:09
  • 11
    @JohnDoe it's not PHP, it's a shell script for bash as indicated by the first line.
    – Peteris
    Commented Mar 25, 2020 at 11:38
  • 4
    Is a bash script, look at the shebang line bash.cyberciti.biz/guide/Shebang
    – Dave
    Commented Mar 25, 2020 at 11:39
  • 10
    @JohnDoe Since you aim to do some security testing, you could show a bit of willingness to learn something new and set up a Linux VM to run the script there.
    – MechMK1
    Commented Mar 25, 2020 at 13:38
  • 9
    No need for a full-blown VM. Just install cygwin shell and you are good. If you work with git, you might even already have a shell as the standard git shell on windows is a minGW based bash.
    – Manziel
    Commented Mar 25, 2020 at 15:57
8

Few other answers calculate how many trailing zeros you need to append, then they append. In Linux there's this simple way:

truncate -s 5MB image

(this assumes you want 5 MB, i.e. 5*1000*1000 bytes. For 5 MiB, i.e. 5*1024*1024 bytes, use -s 5M).

If originally image is larger than the specified size, then the extra data will be lost. If originally image is smaller, then padding zeros will be added. Added fragment will be sparse, if possible.

If for any reason you don't want sparseness, use fallocate:

fallocate -l 5MB image

(similarly, yet not identically: -l 5MB for 5 MB, -l 5MiB for 5 MiB).

fallocate used this way can only extend image. If the file is already at least that big then its size won't change (sparseness can change, I won't elaborate).

2
  • your comment is nice for create generic file. not just image. and the question ask about image specific.
    – ofir_aghai
    Commented May 1 at 12:21
  • for example you can do the same with fsutil file createnew file_less_than_3mb 3070000 but this not answer the question..
    – ofir_aghai
    Commented May 1 at 12:23
4

if you insist on Windows - I suggest going to CMD , find a suitable small file ...

>copy /B file1+file1 file2 while replacing file1 and file2 with suitable filenames .. you can repeat said copy command by using file2 as source (first 2 names) .. the files will be binary concatenated - so you get a target file of increasing size - until you are satisfied

not as nice as a script - but it works out of the (windows)-box only needs 1 source file .. that doesn't even necessarily has to be an image - as mime-type for uploads mostly is determined by the file-ending

3

Does it have to be any specific format? For instance, would a BMP file do?

Uncompressed BMP files are exactly that: completely uncompressed. Thus, each pixel takes up a fixed amount of storage, so it's just a matter of working backwards from the file size you want to the dimensions of the image. So, for an 8-bit BMP, in theory you'd need a 5 megapixel image to get a 5 megabyte file.

Unfortunately, there are a few things that complicate the calculation somewhat:

  1. You're going to have to take the size of the BMP header into account. There are several different versions of the format, each with a different header size, so you'll need to experiment with your image editor to figure out what size header it produces.

  2. Each line of the image is padded to be a multiple of four bytes, so there might be a few extra bytes per line.

  3. BMP files can be compressed, indexed, and have color profile information included. These options are rarely used, but they are out there. If your graphics program uses these and you can't turn them off, your size calculation is going to get a lot more complicated (if it's even possible at all).

2

One can use https://iamtester.ru/ (gratis):

enter image description here

Example with bytes = 700000 (i.e., 700 KB) and type = PNG:

enter image description here

FYI, related: Make a GIF image with an exact given byte size.

1
  • thanks! works great.
    – ofir_aghai
    Commented May 1 at 12:24

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .