Note that, if it's about padding with 0 bytes to align to some boundary, you can use dd with conv=sync for that.
$ echo test | dd bs=128 iflag=fullblock conv=sync | hexdump -Cv
0+1 records in
1+0 records out
128 bytes copied, 5.9459e-05 s, 2.2 MB/s
00000000  74 65 73 74 0a 00 00 00  00 00 00 00 00 00 00 00  |test............|
00000010  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
00000020  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
00000030  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
00000040  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
00000050  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
00000060  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
00000070  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
00000080
(iflag=fullblock is a GNU extension¹, but is only needed for pipe inputs or more generally when there could be short reads, not for regular files; with GNU dd, you can also add status=none to remove the transfer information).
Or you can use truncate on an already existing file to a larger size, for the end to be filled with NULs (not taking any more space on disk):
$ echo test > file
$ truncate -s 1M file
$ hexdump -C file
00000000  74 65 73 74 0a 00 00 00  00 00 00 00 00 00 00 00  |test............|
00000010  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
*
00100000
Or the same with fallocate -l in place of truncate -s to allocate the disk space.
Note that among the shells that have copied zsh's {x..y}, bash is the only one where {1..$n} doesn't work, so here, you could also switch to one of those shells (zsh, ksh93, yash -o brace-expand).
In zsh:
$ hex=00; n=100; printf "\x$hex%.0s" {1..$n} | hexdump -Cv
00000000  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
00000010  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
00000020  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
00000030  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
00000040  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
00000050  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
00000060  00 00 00 00                                       |....|
00000064
zsh also has padding operators and (contrary to bash) can store arbitrary bytes in its variable:
$ string=test n=128 pad=$'\0'; printf %s ${(pr[n][$pad])string} | hexdump -Cv
00000000  74 65 73 74 00 00 00 00  00 00 00 00 00 00 00 00  |test............|
00000010  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
00000020  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
00000030  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
00000040  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
00000050  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
00000060  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
00000070  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
00000080
(beware, padding is based on number of characters, use set +o multibyte for it to be byte-wise in locales where characters can be made of more than one byte).
¹ Since added to the 2024 edition of the POSIX standard, but currently with an unfortunate typo as they have iflags=fullblock instead of iflag=fullblock, typo copied from the request to add that GNU extension to the standard.
     
    
>>append was moved to after thedone. That would only open the output file for append once, instead of 65515 times.