nanoboard client + sources in a single zip: https://github.com/nanoboard/nanoboard/releases
Внимание! Статья устарела и нуждается в обновлении
За время существования статьи спецификации поменялись и дополнились такими элементами как капча и Proof Of Work...
- Модераторский произвол
- Мечта о неубиваемой борде
- простота формата нанопостов: хэш + текст сообщения = хэш (на который могут ссылаться другие нанопосты)
- отсутствие владельца, прав, уровней доступа, невозможность централизованной модерации или отключения наноборды
- отсутствие стандартизированного протокола распространения, в самой простой форме нанопост можно скопировать и вставить как текст
- паразитирование на существующих ресурсах в интернете и скрытом интернете вместо организации p2p-соединений и/или серверов (низкий уровень детектирования + эксплуатация чужих мощностей)
- поощряется помощь участникам и наноборде в виде ретрансляции чужих нанопостов (кроме огромных)
- клиенты для просмотра собирают все нанопосты воедино и формируют цепочки - так сохраняется логическая связь между нанопостами и отпадает необходимость во временных метках (подверженных фальсификации)
- клиенты для просмотра должны давать участнику возможность легко фильтровать нежелательный мусор, чтобы не видеть его и не распространять
- клиенты для просмотра облегчают участнику распространение своих и чужих нанопостов (кроме мусора)
- клиенты для просмотра ограничивают распространение слишком огромных чужих нанопостов, чтобы пресекать злоупотребление "трафиком" наноборды
Каждый нанопост обязательно ссылается на другой нанопост поредством хэш-кода.
Хэш код 16-байтовый и выглядит как 32-символьный кусочек текста в шестандцатиричном текстовом виде.
Рассмотрим пример на JavaScript.
Нам понадобится SHA-256, взять можно например отсюда: http://www.movable-type.co.uk/scripts/sha256.html
или отсюда: https://username1565.github.io/sha256/sha256_utf8.html
var post = "00000000000000000000000000000000{Welcome to Nanoboard}"
var hash = Sha256.hash(post).substring(0,32) // берём хэш f682830a470200d738d32c69e6c2b8a43b44435f48ba000cfb5203b22e9bf026 в hex и отбрасываем всё кроме первых 32 символов
console.log(hash) // результат: f682830a470200d738d32c69e6c2b8a4
Хэш считается с байтов utf-8 кодировки. В nboard этот пост и его хэш используются как "корневые" но это не обязательно.
Теперь попробуем "ответить" на корневой пост.
var answer = hash + "Проверка ответа."
console.log(answer) // результат: f682830a470200d738d32c69e6c2b8a4Проверка ответа.
Ответим снова.
function getHash(content) { return Sha256.hash(content).substring(0,32); }
var answer2 = getHash(answer) + "Второй уровень."
console.log(answer2) // результат: 77bb9e5d1a64facc551210862e2c6536Второй уровень.
Вот так выглядят нанопосты, естественно, внутри можно ставить переносы строк и любые utf-8 символы.
Теперь осталось только распространить их. По хэшам все связывается в цепочки. Сложно сказать что является тредом среди нанопостов.
Определенно если на нанопост существует несколько ответов то с него можно начинать просмотр "треда".
Начать разворачивание можно с любого уровня, это уже на плечах реализаций просмотрщиков Наноборды.
В nboard можно разворачивать любые нанопосты кроме корневого, а можно просто просматривать только сам нанопост
и его ответы (следующий уровень).
Из нанопостов, формируется удобная для хранения структура данных - хеш-таблица, которая может быть распределённой - DHT.
Именно диверсификация этой хэш-таблицы, делает наноборду - принципиально-неубиваемой и немочерируемой, несмотря на то, что возможно локальное удаление нанопостов, в случае вайпа, и для этого сделано всё возможное, в том числе и система репортов.
Наноборда берет начало с Анонимных Имидж Борд, Имидж означает наличие картинок (image).
Хотя существуют чисто текстовые борды, наноборда такой не является, потому как внутрь можно вставлять base64-изображения.
В nboard это реализовано так: если в нанопосте встречается конструкция вида [img=.....]
(где вместо точек - base64 строчка), то всё это дело превращается в изображение.
Кроме того nboard поддерживает разметку:
[b]жирный[/b], [i]курсив[/i], [s]перечеркнутый[/s], [sp]спойлер[/sp], [u]подчёркнутый[/u], [g]зелёный[/g].
Также, возможно распространять в виде base64 - любые файлы (размером до 65535 байт).
В основном, это zip-архивы, но могут быть и любые другие файлы.
Файлы, могут быть прекриплены, как JPEG-картинка, без сжатия, тогда, в нанопосте, используется:
-
либо старая конструкция [xmg=.....], где вместо точек - base64 несжатого файла,
В этом случае, когда скрипт наноборды находит тег xmg, он автоматически добавляет ссылку на закачку zip-архива,
превращая её в dataURL.
-
либо же используется bb-код file, с именем и типом файла - как у карасика.
Тогда, при парсинге, имя файла попадает в ссылку, в атрибут download, а тип файла - в dataURL,
и бинарный файл - можно закачать, по ссылке.
На АИБ обычно можно свободно постить PNG-картинки. А в PNG-картинку можно вшить данные.
В nboard используется подход (и, собственно, код) из этой статьи: http://blog.andersen.im/2014/11/hiding-your-bits-in-the-bytes/
Вкратце суть в том что информация размещается в нижних битах компонентов R, G и B каждого пикселя
и это совершенно незаметно на глаз.
Разница между 24битным цветом и 21битным цветом с дизерингом (информациионный шум), по сути - минимальна.
Размер картинки после этого обычно увеличивается но не разительно.
Информация хранится именно в пикселях, что позволяет скопировать картинку в буфер обмена,
вставить в графический редактор, сохранить, скажем, в BMP, а потом пересохранить в PNG - вшитая информация не пропадёт.
Итак nboard берет некоторое количество свежих (по дате поступления на компьютер пользователя) постов,
а также некоторое количество случайно выбранных постов за всё время.
При этом избегаются скрытые пользователем посты, а крупные посты отправляются только если являются свежими.
В наноборде карасика также имеется кнопка "В очередь" и "Из очереди",
позволяющая тонко настроить список очереди нанопостов, для упаковки их оттуда - в контейнер.
Случайные посты, можно также отключить там.
Но это там...
Здесь же, упаковка массива постов происходит следующим образом:
public static byte[] Pack(NanoPost[] posts)
{
List<byte> bytes = new List<byte>();
// количество постов (от 000000 до ffffff) (строчка в utf-8 байтах):
bytes.AddRange(Encoding.UTF8.GetBytes(posts.Length.ToString("x6")));
foreach (var p in posts)
{
// количество символов (не байтов!) в нанопосте (включая родительский хэш):
var len = p.SerializedString().Length;
// тот же формат: от 000000 до ffffff (строчка в utf-8 байтах):
bytes.AddRange(Encoding.UTF8.GetBytes(len.ToString("x6")));
}
foreach (var p in posts)
{
// utf-8 байты каждого поста по очереди без разделителей:
bytes.AddRange(p.SerializedBytes());
}
// сжимаем результат gzip-ом
return GZipUtil.Compress(bytes.ToArray());
}
Перед упаковкой в контейнер (после сжатия gzip-ом) применяется шифрование salsa20 по некоторому ключу.
Для Наноборды пока есть один общий ключ, но дальше можно отделяться в отдельные зашифрованные Наноборды
(что нежелательно но иногда может быть необходимо):
// Параметры инициализации salsa20 для заданного ключа (key):
byte[] initKey = SHA256.Create().ComputeHash(Encoding.UTF8.GetBytes(key));
byte[] initVec = SHA256.Create().ComputeHash(Encoding.UTF8.GetBytes(key).Reverse().ToArray());
initKey = initKey.Crop(32);
initVec = initVec.Crop(8);
На этом пока что всё.
Напомню, что PNG-контейнеры - не единственный возможный способ обмена нанопостами
и различные АИБ - не единственное возможное место для паразитирования.
Одна из экстремальных идей - запихивание нанопостов в QR-коды и разбрасывание/расклеивание этих QR-кодов в местах,
где их будет удобно считывать (и, собственно, наклеивать/разбрасывать).
Так Наноборда сможет продолжить существование даже без Интернета, например, в метро.
Разумеется, вариант почти фантастический, но пример демонстрирует гибкость и ту самую неубиваемость Наноборды.
Ведь используя один лишь смартфон, с приложением в виде сканера qr-кодов,
даже в метро можно декодировать из qr-кода - коротенькую magnet-ссылку,
вытащить по ней - пак пикч из облачного торрента,
распарсить эти picture в бункере, на нейрокомпьютере, и залезть в нанабороду.
Алсо, может быть привинчена - IRC-координация (а это технология, она неубиваема, ага),
Tox (а там - ассиметричная криптография на библиотеке NaCl),
p2p (а там вообще - тотальная децентрализация пиринговых сетей же),
и многое другое...
nanodb.exe-source from https://github.com/nanoboard/nanoboard/releases/download/0/nanoboard-restore.zip nanoboard-restore\nanodb.exe-source Version: Client 3.0 Language: C#
Q: How to compile nanodb.exe? A:
- Win+R
- cmd, enter.
- disk:\Path_to_.NET_Framework\MSBuild.exe /property:Configuration=Release nanodb.csproj
Q: Is nanodb.exe portable? A: No, this working with files from restore-archive.
See updates here: https://github.com/username1565/nanoboard/releases/
Commits: here: https://github.com/username1565/nanoboard/network