На днях состоялся первый релиз набора инструментов для упаковки различных веб-ресурсов в один файл — Web Bundle. Принцип его работы точно такой же, как для ресурсов, включаемых в EXE файлы — произвольные файлы упаковываются в один файл-контейнер, а на клиентской стороне доступ к ним организуется по имени файла с помощью API. Только в данном случае в качестве контейнера используется изображение в формате PNG. Клиентская часть представляет из себя небольшую JS-библиотечку, позволяющую загружать, декодировать и извлекать отдельные файлы из таких ресурсов.

Тут должна быть картинка с троллейбусом из буханки. Круто, но зачем?! Ведь все ресурсы прекрасно загружаются и без упаковки в контейнер, да еще и параллельно. Это вопрос неоднозначный. С одной стороны, загрузка ресурсов одним файлом может быть быстрее, чем даже параллельная загрузка множества мелких файлов, особенно на мобильном подключении с высокими задержками. С другой стороны, давно есть технологии для объединения однотипных ресурсов в один файл, таких как скрипты, таблицы стилей, иконки. Да и широкое распространение HTTP 2.0 в скором времени должно решить эту проблему. Но все же у Web Bundle есть некоторые преимущества.

Универсальность. Упаковывать можно абсолютно любые файлы, вплоть до бинарных. На некоторых хостингах с ограничениями на MIME тип загружаемых файлов невозможно ни загрузить, ни отдать клиенту произвольный файл.

Быстрое декодирование. Формат PNG декодируется самим браузером, на выходе получается «изображение», которое визуально ничего осмысленного не несет и выглядит, как цветной шум. Вместо значений цветов пикселей находится содержимое файлов-ресурсов, которое извлекается клиентской библиотекой с помощью Canvas.


В этом изображении находятся три файла

Для удобства предусмотрены методы чтения ресурса как текста, как JSON объекта и как изображения.

Успех этой технологии будет зависеть от того, найдется ли ей реальное применение. Причем оно может оказаться самым разным. Например, может ли она быть использована для скрытой доставки malware на клиента? Наверное может. Но AV вендоры скорее всего отреагируют быстро и добавят соответствующий модуль распаковки и анализа. Так что для пользователей это не будет большой проблемой. А вот для всяких фото- и скриншот-хостингов может стать проблемой, если им придется сканировать все загружаемые пользователями файлы, это увеличит нагрузку на сервера.

UPD:
Как подсказал iSage, эта идея уже была реализована в PNGfy в 2009 году (надо же, Canvas был уже тогда!), правда, только для одного файла.

Комментарии (23)


  1. MichaelBorisov
    04.04.2015 16:16
    -1

    Поздравляю авторов!

    Патент уже получили?

    А насчет этого:

    добавят соответствующий модуль распаковки и анализа

    не факт, что это поможет. Модуль сможет распаковывать только те данные, которые закодированы в описываемом стандарте. Автор же малвари может придумать подобный, но свой формат упаковки данных в картинки, вплоть до стеганографического, когда при просмотре такой картинки человек даже будет видеть осмысленное изображение.


    1. Maccimo
      05.04.2015 08:03

      >> Модуль сможет распаковывать только те данные, которые закодированы в описываемом стандарте.

      На самом деле — не обязательно.
      Модуль вполне может анализировать код распаковщика и восстанавливать алгоритм упаковки. Если по какой-либо причине восстановить алгоритм не получилось, но ясно, что где-то здесь идёт распаковка — ругаться нехорошими словами.


  1. iSage
    04.04.2015 16:44
    +5

    some.geekly.info/pngfy.html / code.google.com/p/pngfy/ Вы опоздали лет на 5. Вообще, это еще hid.im придумали (и, судя по тому, что больше упоминаний об этом у них нет — не взлетело)


    1. ComodoHacker Автор
      04.04.2015 17:28

      Спасибо, добавил в топик!



      1. Jeditobe
        04.04.2015 22:39

        И вот была публикация
        habrahabr.ru/post/102394/


  1. Goodkat
    04.04.2015 20:14
    +5

    Если отдавать этот PNG не по https, то может всё сломаться — некоторые опсосы и браузеры сжимают картинки для экономии.


  1. binarydao
    04.04.2015 20:33
    +1

    «изображение», которое визуально ничего осмысленного не несет и выглядит, как цветной шум

    Преимущество rarjpg было именно в возможности незаметно передавать информацию в обычном, казалось бы, изображении. А для этого «изобретения» пока не придумали применения.


    1. DarkByte
      05.04.2015 06:45

      Некоторые облачные хостинги не считают занимаемое место файлами типа «фотографии», при условиях не превышения определённого разрешения и веса. Пакуем важные файлы с шифрованием в png и заливаем на подобные хостинги (можно сделать драйвер ФС на fusefs), получаем надёжное, бесплатное и безлимитное хранилище для важных (и не очень) файлов.


      1. Goodkat
        05.04.2015 21:33

        получаем надёжное, бесплатное и безлимитное хранилище И очень медленное.


        1. bolk
          05.04.2015 22:47

          Почему медленное? Те же «Яндекс.Фотки» — быстрое, безлимитное хранилище


  1. elmortem
    04.04.2015 20:49
    +4

    В своё время в разработке игр на флеше использовали метаданные jpeg для сохранения уровней, сделанных пользователями. Уровень сохранялся в виде картинки с превьюшкой уровня и внутри него была вся информация о самом уровне.
    А тут просто каша из пикселей, скучно.


  1. rumkin
    04.04.2015 21:25

    Я думаю, что в ближайшие год-два с распространением http/2 появится стандарт бинарного контейнера для веба наподобие CBOR, BSON или MsgPack и необходимость в столь изощренных способах упаковки данных исчезнет.


  1. DjPhoeniX
    05.04.2015 00:36
    +3

    Внедрял такое на одном своём ресурсе, только использовал чёрно-белые изображения — они лучше жмутся optipng.


    1. ComodoHacker Автор
      05.04.2015 07:20
      +1

      Что именно упаковывали, если не секрет?


      1. DjPhoeniX
        05.04.2015 15:20

        Объединённые JS/CSS (в minified в сумме около 400кб), в RGB (3 байта на пиксель) пожалось до 80кб, в grayscale — до 50кб.
        Сейчас повторил с обновлённой версией optipng — разница уже не такая существенная. А на некоторых файлах и вовсе RGB выигрывает. В общем надо индивидуально подбирать.


        1. grossws
          05.04.2015 20:40

          А если сравнить с minified версиями после обыкновенного gzip/deflate?


          1. DarkByte
            05.04.2015 21:40

            Существенный выигрыш сжатия png относительно минифицироанных версий скриптов заключается только в том, что первый использует всю таблицу символов, а во втором случае только печатные символы. А если сравнивать gzip и png, то особой разницы в сжатии не будет.


            1. grossws
              05.04.2015 22:30

              Существенный выигрыш сжатия png относительно минифицироанных версий скриптов заключается только в том, что первый использует всю таблицу символов, а во втором случае только печатные символы.
              Не только. PNG может ещё какой-нибудь deflate на данные применять, что приводит к сравнению оверхеда при разных подходах (deflate при HTTP против заголовков самого png + распаковщика, который вытащит данные из png).

              Минифицированный скрипт/css ещё требует соблюдения синтаксиса соответствующего языка, что ещё повышает энтропию и, значит, потенциальную возможную степень сжатия.


  1. roman01la
    05.04.2015 14:43

    Есть черновик спеки Packaging on the Web w3ctag.github.io/packaging-on-the-web/


  1. RPG
    05.04.2015 23:35

    Вместо значений цветов пикселей находится содержимое файлов-ресурсов, которое извлекается клиентской библиотекой с помощью Canvas.

    Насколько я понимаю, чтение такого canvas будет «греть атмосферу» несколько секунд, что при загрузке веб-страницы совершенно неприемлемо. Хотелось бы увидеть в статье, насколько замедлилась загрузка страницы благодаря такой «оптимизации» по сравнению с несжатым аналогом.


    1. ComodoHacker Автор
      06.04.2015 05:45

      чтение такого canvas будет «греть атмосферу» несколько секунд
      Не думаю, что все так плохо. Насколько я понимаю, GetImageData() — нативный метод, загружающий данные в массив. Но тестов я не проводил.


  1. subzey
    06.04.2015 00:44

    Очень похожая техника используется в JsExe для упаковки демок на джаваскрипте