Как создать файл размером X байт, который не сжимается с помощью zip

Изучив исходный код программы beep, я придумал минимальную программу на языке C, которая звонит в колокольчик.

Он использует динамик ПК, который ядро ​​Linux делает доступным как устройство evdev, обычно называемое/dev/input/by-path/platform-pcspkr-event-spkr(символической ссылкой на фактическое местоположение ).

Существует одно событие для включения динамика (, т.е. для начала воспроизведения звука )на заданной частоте, и другое событие для выключения динамика (, т.е. для остановки звука ). Мы просто отправляем первое событие, затем спим необходимое время, затем отправляем второе событие.

Для этого требуется доступ на запись к устройству, который можно настроить с помощью правила udev, бита setuid для программы или запуска программы от имени пользователя root, как описано в документации beep. Кроме того, это не может контролировать громкость звука. Почему-то программа xset(из комплекта X-серверов )и эмуляторы терминала не имеют этих ограничений.

В Си

#include   // struct input_event
#include   // open
#include   // write, close
#include   // nanosleep

/* frequency (Hz): */
static unsigned int const default_frequency = 440;
/* duration (ms): */
static unsigned int const default_duration = 200;
/* file path of PC speaker: */
static char const * const default_device = "/dev/input/by-path/platform-pcspkr-event-spkr";

void start_beep(int fd, int freq)
{
    struct input_event e = { 0 };
    e.type = EV_SND;
    e.code = SND_TONE;
    e.value = freq;
    write(fd, &e, sizeof(e));
}

void stop_beep(int fd)
{
    start_beep(fd, 0);
}

void sleep_ms(unsigned int ms)
{
    struct timespec duration =
        {.tv_sec  = ms / 1000U,
         .tv_nsec = (long)(ms % 1000UL * 1000UL * 1000UL) };
    nanosleep(&duration, NULL);
}

int main(void)
{
    int fd = open(default_device, O_WRONLY);
    start_beep(fd, default_frequency);
    sleep_ms(default_duration);
    stop_beep(fd);
    close(fd);
    return 0;
}

(Для краткости и ясности приведенный выше исходный код пропускает все проверки безопасности (проверяет существование файла, проверяет успешность open, проверяет, что файловый дескриптор является символьным устройством, проверяет, что частота и продолжительность являются целыми числами в пределах допустимого диапазона, проверьте успешность write, проверьте успешность nanosleep… ). В реальном приложении это должно быть решено.)

В сценарии оболочки

Приведенную выше программу на C можно использовать для наблюдения за формой событий; затем те же события могут быть записаны из сценария оболочки. К сожалению,двоичный формат, скорее всего, зависит от платформы -. На моей машине x86 -64 с ядром Linux 5.2 звуковое событие имеет следующую структуру:

  • 16 байт :ноль
  • 2 байта, маленький -порядок байтов :0x12 (поле typeсо значениемEV_SND)
  • 2 байта, маленький -порядок байтов :0x2 (поле codeсо значениемSND_TONE)
  • 4 байта, маленький -порядок байтов :частота в Гц или 0 для остановки звука (полеvalue)

Эта бинарная структура может быть написана с использованием Perl с помощью функцииpack. Двоичные целые числа также могут быть выведены с использованием чистого Bash , но это более подробно.

# frequency (Hz):
default_frequency=440
# duration (ms):
default_duration=200
# file path of PC speaker:
default_device='/dev/input/by-path/platform-pcspkr-event-spkr'

function start_beep()
{
    declare -i freq="$1"
    perl -e 'print pack("qqssl", 0, 0, 0x12, 2, '$freq')'
}

function stop_beep()
{
    start_beep 0
}

# USAGE: beep [FREQUENCY [DURATION [DEVICE]]]
function beep()
{
    declare -i freq="${1-$default_frequency}"
    declare -i dur="${2-$default_duration}"
    declare dev="${3-$default_device}"
    # convert milliseconds to seconds
    declare dur_sec=$( printf '%u.%03u' $(( dur / 1000 )) $(( dur % 1000 )) )
    # write the sound events
    {
        start_beep $freq
        sleep $dur_sec
        stop_beep
    } >> "$dev"
}

0
28.10.2021, 01:12
1 ответ
dd if=/dev/urandom of=file bs=1M count=400

Будет создан файл file, который zip вообще не сможет сжать. Zip также не сможет сжимать ранее сжатые данные, включая видеофайлы.

2
28.10.2021, 05:24

Теги

Похожие вопросы