Как своими руками сделать WiFi камеру слежения (ESP32-CAM)

К старту курса по разработке на С++ рассказываем, как самостоятельно собрать IP-камеру с обнаружением движения. За подробностями приглашаем под кат, где вы найдёте много фотографий и видео на Youtube-канале автора, за которым наблюдают более 30 000 человек.


Хотя не все хорошие WiFi камеры наблюдения дороги, большинство из них стоят немало, особенно если брать для дома сразу несколько. Сегодня мы за небольшие деньги (около 20 долларов, цена зависит от того, что у вас уже есть) сделаем беспроводную камеру с модулем ESP32-CAM AI thinker WiFi (одной из лучших макетных плат для камер), чтобы наблюдать за происходящим в доме или снаружи.

Введя уникальный IP-адрес в браузере, с этой камеры можно войти на веб-сервер и просматривать видео, а также менять настройки на боковых панелях управления. Благодаря коду, когда что-то или кто-то движется перед камерой, начинается запись, а записанные видеофайлы .MJPEG сохраняются на SD-карту. В камере слежения есть ещё много функций, но о них позже. А сейчас приступим к её сборке. Вот ссылка на видео проекта на YouTube.

Что нам потребуется
  • модуль ESP32-CAM с датчиком камеры OV2640 на 2 Мпикс;

  • конвертер с USB-порта FTDI на последовательный (для программирования) + соединительные провода между гнёздами;

  • карта microSD на 4 Гб (карта памяти TF);

  • антенна с фиксатором;

  • литий-ионный зарядный модуль TP4056 на 1 ячейку;

  • батарея 18650 3,7 В 2600 мАч (2 шт.);

  • ползунковый мини-переключатель SPDT (лучше тумблер 3 A);

  • провода диаметром 0,51 мм;

  • красный светодиод 3 мм;

  • резистор на 220 Ом;

  • цилиндрический пластиковый контейнер (выбор корпуса камеры — за вами);

  • крепление камеры к стене для GoPro.

1. Программирование ESP32-CAM

Загружаем код ESP32-CAM_MJPEG2SD в ESP32-CAM (спасибо пользователю s60sc на GitHub: он выложил последнюю версию кода). Всю информацию о коде смотрите по ссылке.

Чтобы запрограммировать модуль камеры, соединяем его с конвертером FTDI, работающим с USB и последовательным портом, как показано на схеме выше. Здесь подключаем пин GPIO 0 к GND, что позволяет программировать ESP. Нажимаем кнопку сброса на задней части платы модуля камеры, чтобы включить режим вспышки перед загрузкой.

2. ESP32.json

Прежде чем переходить к коду, добавим во вкладку Preferences («Предпочтения») в Arduino IDE ссылку ESP32 .json, дающую доступ к примерам кода, библиотекам и так далее:

3. Заполнение параметров в коде

Открываем загруженный код камеры слежения ESP32-CAM_MJPEG2SD:

Раскомментируем строку CAMERA_MODEL_AI_THINKER, если у вас эта плата:

Вводим необходимые параметры, такие как модель камеры, а также учётные данные WiFi:

Дополнительно вводим данные FTP, чтобы получать записанные видео удалённо:

4. Загрузка кода на плату

Выбираем плату, скорость загрузки, частоту и режим вспышки, схему разделов, основной уровень отладки и COM-порт:

Нажимаем Upload  («Загрузить»). Загрузка на плату небыстрая: чуть подождём:

Ссылка на код.

5. Подготовка ESP32-CAM и получение IP-адреса

Обязательно отсоединяем провод от IO0 к GND:

И нажимаем кнопку сброса:

Вставляем в слот модуля карту MicroSD. Минимум 4 Гб:

И получаем уникальный IP-адрес с монитора порта. Нужная кнопка в правом верхнем углу Arduino IDE.

6. Веб-сервер ESP32-CAM

После ввода IP-адреса в веб-браузер при включённой камере появится такая страница:

Нажав кнопку Start Stream («Начать трансляцию»), начинаем просмотр видеопотока:

Последняя версия кода даёт возможность начинать и останавливать запись вручную. Ранее запись запускалась лишь при обнаружении движения.

7. Сборка камеры

Для корпуса выбираем контейнер или материал, с которым легко работать. С вставкой железа в сплющенную трубу из ПВХ (показана ниже) возникли проблемы, поэтому используем цилиндрический пластиковый контейнер. Подробнее об этом читайте далее.

На картинке не совсем те детали, что использовались.

Для сборки понадобится
  • ESP32-CAM;

  • плата для заряда батарей TP4056 1S;

  • Li-Ion батарея 18650 3,7 В;

  • ползунковый мини-переключатель SPDP или тумблер 3 A;

  • красный светодиод 3 мм;

  • резистор мощностью 1/4 Вт 220 Ом;

  • антенна;

  • провод диаметром 0,51 мм;

  • крепёжный винт GoPro.

8. Подключение платы для внешней антенны

Выпаиваем резистор 0 Ом, соединяющий ESP с его антенной на плате:

И припаиваем его, подключая ESP к порту внешней антенны:

Этот этап нужен, чтобы увеличить диапазон для подключения собственной антенны.

9. Подключение источника питания ESP32-CAM

Подключаем к батарее зарядную плату TP4056 4,2 В (соединения B+ и B– от платы к батарее показаны выше):

К клеммам батареи подключаем входы платы рядом с портом Micro USB:

10. Работа с соединениями компонентов

Выпаиваем штыревые разъёмы ESP32-CAM с обеих сторон и удлиняем их, припаивая обратно с проводами.

Добавляем индикатор питания (красный светодиод):

Чтобы не запутаться, подбираем цвета проводов по их назначению:

11. Схема соединений

По этой простой схеме подключений должна получиться домашняя камера слежения со всем её железом.

12. Выбор батарей и корпуса

Сначала был плоский Li-Ion аккумулятор, я заменил его на батареи, более компактные для нового, цилиндрического корпуса:

Чтобы камера работала хорошо, лучше использовать батарею ёмкостью более 2000 мА·ч:

В итоге параллельно использовали 2 батареи 18650 по 3,7 В и 2600 мА·ч, что дало в сумме 5200 мА·ч. Приличная ёмкость.

13. Подготовка железа к установке в корпус

Отмечаем и сверлим отверстия для выступающих из корпуса частей:

Выбираем корпус для камеры, состоящий из двух частей: с таким легко работать. Лучше распечатать его на 3D-принтере.

14. Установка в корпус

Клеим двусторонний скотч или ленту на батареи и модуль ESP32-CAM (сверху и снизу):

Вставляем их в корпус:

Места с выступающими компонентами герметизируем термоклеем:

15. Защита от воды

Крепим детали к корпусу термоклеем, если нужно:

Чтобы вода не попала внутрь, место стыка половинок заклеиваем изолентой:

Нарезаем кусочки резины и вставляем в любые зазоры/отверстия, например порт Micro USB сзади и слот SD-карты спереди вверху:

16. Тестирование камеры

Вставляем карту MicroSD в слот камеры, а кусочек резины обратно, включаем камеру переключателем сзади, и находим веб-сервер IP-камеры (см. этапы 5 и 6):

Процедура запуска камеры и поиска её веб-сервера та же, но без нажатия кнопки сброса, ведь снова программировать камеру не нужно:

В меню веб-сервера камеры нажимаем кнопку Start Stream («Начать трансляцию») и получаем видеопоток в реальном времени:

17. Панель видеопотока

На этой панели есть вся подробная информация о ходе записи, освещённости (в ночное время), свободном месте на карте памяти, а также о дате и о температуре камеры. Здесь даже кнопкой переключается светодиод на плате ESP, отображается движение, обнаруженное ИИ, меняется чувствительность определённых функций и т. д.:

Чтобы менять разрешение записи (не только просмотра), открываем вкладку разрешения и выбираем более низкое или даже более высокое (наибольшее — 1600 × 1200). Во вкладке Get Folder («Получить папку») просматриваем записанные видео, нажимая кнопку Start Stream:

18. Крепление к стене

Можно взять держатель или кронштейн для крепления камеры к стене или любой другой поверхности. Здесь используется комплект креплений для экшн-камеры:

19. Включение камеры через USB

Подключаем источник питания на 5 В к зарядному модулю Micro USB (с кабелем от зарядника телефона) в задней части камеры:

Прикреплённая к стене камера должна работать постоянно:

Так идёт подзарядка батарей и непрерывное питание ESP32-CAM.

Батарея пригодится, если нужно снимать там, где нет розетки. Но на всю ночь её не хватит.

20. Очистка

Заполненную карту microSD извлекаем, подключаем к компьютеру и просматриваем файлы .MJPEG в проигрывателе:

21. Запись

В левой части экрана телефона отображается состояние Recording («Запись»):

Когда в кадре есть движение, камера записывает, когда его нет — прекращает запись.

22. Заключение

Вот и всё:

Теперь у вас есть собственная классная WiFi камера слежения:

Она сделает ваш дом ещё безопаснее:

В репозитории на GitHub есть код с расширениями, дополнительной информацией, характеристиками и возможностями ESP32-CAM MJPEG2SD.

Видео

Продолжить погружение в IT вы сможете на наших курсах:

Узнайте подробности здесь.

Другие профессии и курсы


ссылка на оригинал статьи https://habr.com/ru/company/skillfactory/blog/645877/

Мини-ПК в 2022 году: интересные модели, которые могут пригодиться в офисе и дома

Несмотря на все усугубляющийся кризис производства полупроводниковых компонентов, производители электронных устройств поставляют на рынок все новые девайсы. В 2022 году успело выйти немало интересных моделей, которые могут пригодиться как компаниям, так и обычным пользователям. Подробнее об этих моделях — под катом.

Intel NUC 11 Essential

Это новый проект компании Intel c кодовым названием Atlas Canyon. Пока что компьютеры еще не появились в продаже, но некоторые их особенности уже известны. Например, будут доступны модели на базе Intel Celeron N4505, Celeron N5105 и Pentium Silver N6005.

Процессор Cores / Threads Макс. частота GPU execution units Макс. Частота GPU
NUC11ATKC2 Celeron N4505 2 / 2 2.9 GHz 16 750 MHz
NUC11ATKC4 Celeron N5105 4 / 4 2.9 GHz 24 800 MHz
NUC11ATKPE Pentium Silver N6005 4 / 4 3.3 GHz 32 900 MHz

Ранее об этих устройствах стало известно благодаря утечке, и сейчас эта информация подтвердилась.

Что касается прочих характеристик устройств, то размер корпуса составит 135 x 115 x 36 мм. Мини-ПК будут поддерживать вплоть до 32 ГБ ОЗУ (DDR4). Производитель предложит и опцию выбора модели с 64 ГБ eMMC.

Работать можно будет с двумя дисплеями одновременно. Беспроводная связь — WiFi 5 и Bluetooth 5. Вот список портов и разъемов:
• 4 x USB 3.2 Type-A
• 2 x USB 2.0
• 1 x HDMI 2.0b
• 1 x DisplayPort 1.4
• 1 x Gigabit Ethernet
• 1 x 3.5 аудио

Модели, которые получат eMMC-память, скорее всего, будут поставляться с установленной Windows 11. Поддерживать они будут также «десятку» и Linux.

ZX01

За последние несколько лет различные компании стали выпускать мини-ПК, которые помещаются на ладони. Среди этих компаний как ноунейм-китайцы, так и вполне себе известные корпорации.

Сейчас стало известно об очередной модели «наладонного ПК» от китайцев. Модель получила название ZX01, она предоставляет пользователям неплохие возможности, имея при этом совсем небольшой размер в 72 x 72 x 45 мм.

Что касается процессора, то здесь установлен Intel Celeron N5105 Jasper Lake. Он изготовлен по новой архитектуре и является несколько более производительным, чем его «собратья». Графическая подсистема тоже на высоте, его вполне можно использовать в качестве медиацентра или даже играть в не особо «тяжелые» игры. Согласитесь, весьма неплохо для такой крохи.

Список портов и разъемов:
• 2 x HDMI 2.0
• 1 x Gigabit Ethernet
• 1 x USB Type-C
• 3 x USB 3.0 Type-A
• 1 x 3.5 мм аудио
• 1 x microSD

Питание — 12 В, 3 А.

Младшие модели линейки комплектуются 8 ГБ ОЗУ DDR 4 и 128 ГБ SSD. Старшие — 16 ГБ ОЗУ и терабайтным накопителем.

Стоимость девайса — от $180, в отличие от предыдущей модели ПК можно приобрести на AliExpress.

Мини-ПК — весьма интересная тема, но у нас есть и другие статьи, оцените — мы рассказываем о:

Маленьких «малинках» в крупном дата-центре
новых SoC от Apple — M1 Pro и M1 Max
Создании собственного корпуса для сервера

ZBOX Magnus EN

Это уже вовсе не «наладонный ПК», как в предыдущем случае, но все равно, это небольшое устройство, которое может использоваться для самых разных целей. Девайс достаточно мощный, внутри — Intel Core i7-11800H процессор и NVIDIA GeForce RTX 3080, так что здесь уже можно запускать весьма производительные игры. Точнее — любые игры, хоть очень тяжелые, хоть легкие инди-игрушки.

Поставляться будут как модели лишь с материнкой и корпусом, в случае, если пользователь захочет комплектовать девайс сам, так и готовые, собранные компьютеры с предустановленной Windows 11. Процессор Core i7-11800H — 8-ядерный, 16-thread процессор с частотой работы ядер вплоть до 4.6 ГГц.

Список портов и разъемов:
• 1 x Thunderbolt 4
• 5 x USB 3.1 Gen 2 Type-A
• 1 x 2.5 Gbps Ethernet
• 1 x Gigabit Ethernet
• 2 x HDMI 2.1
• 2 x DisplayPort 1.4a
• 1 x 3.5 мм аудио
• 1 SD card

К сожалению, стоимость устройства пока неизвестна, но, как можно догадаться, она вряд ли будет низкой — с такими характеристиками устройство может стоить выше $1000.

Asus PN64 и PN52

Две разных модели мини-ПК от ASUS, на базе Intel Core Alder Lake и AMD Ryzen 5000H. Обе модели проектировались как мощные системы небольшого размера, которые могут справиться с обширным спектром задач. Размер, а это 5.1″ x 4.7″ x 2.2″, небольшой, так что девайс можно поместить позади дисплея и получить свободную поверхность рабочего стола.

Что касается первой модели, то она оснащена слотом M.2 2280, плюс есть коннектор для жесткого диска. Ко всему, устройство поддерживает DDR5-4800. Кроме того, в зависимости от конфигурации в ПК устанавливается WiFi 6 или WiFi 6E.

Список портов и коннекторов:
• 1 x 2.5 Gbps Ethernet
• 2 x HDMI 2.0
• 2 x USB 3.2 Gen 2 Type-C
• 3 x USB 3.2 Gen 2 Type-A
• 1 x 3.5 мм аудио
• 1 x конфигурируемый порт (HDMI 2.1, DisplayPort 1.4, VGA, COM или RJ45)

У второй модели — значительный прирост производительности по сравнению с прошлогодним Asus PN51. Пользователь получает 1.3X CPU и 2X GPU, что порадует многих.

Список портов и коннекторов:
• 2 x USB 3.2 Gen 1 Type-C
• 1 x USB 3.2 Gen 2 Type-A
• 4 x USB 3.2 Gen 1 Type-A
• 2 x HDMI
• 1 x 3.5 мм аудио
• 1 x конфигурируемый порт ( HDMI 2.1, DisplayPort 1.4, VGA, COM, 2.5G LAN, и COM)

Первая и вторая модели будут доступны со второй половины 2022 года по цене от $369.

Partaker

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

Поддерживает устройство freeBSD и Linux, включая OPNSense и Untangle. Работает мини-ПК также с Windows, так что проблемы в поддержке разных платформ здесь нет.

Вдобавок к Ethernet-портам предлагается 4 USB 3.0, HDMI и RJ45 COM. Есть также кнопка включения и reset. Установить можно вплоть до 64 ГБ ОЗУ DDR4-3200. Есть коннекторы для SSD и обычного жесткого диска.

Стоимость ПК — от 400 до 800 евро. Оно уже в продаже, как на AliExpress, так и на Amazon.


ссылка на оригинал статьи https://habr.com/ru/company/selectel/blog/598901/

Дорога на Запад. Геодезия и Отвага

Это продолжение истории Экваториальной Градусной экспедиции в XVIII веке отправившейся к, как следует из названия, экватору, чтобы уточнить форму Земли.

Мы расстались на том, что судно «Портофе» не успело отплыть от родных берегов Франции, а некий очень уязвленный успешный математик Пьер Моро де Мопертюи предложил Академии Наук и графу Морепа организовать новую альтернативную экспедицию: на север. Так будет короче, дешевле и эффективнее. Все это замечательно, конечно, но новая экспедиция — это, в любом случае, новые расходы. Почему же Морепа согласился их терпеть? Что не так было с Луи Годеном?

От Рошфора до Мартиники путь был неблизкий. Занял три месяца.
От Рошфора до Мартиники путь был неблизкий. Занял три месяца.

В команде экваториальной экспедиции практически с самого начала наметилось нездоровое противостояние. Луи Годен, державший казенные деньги и паспорта, показал себя крайне высокомерным начальником. Атмосфера была настолько напряжённой, что несколько человек младшего технического состава (именно их и третировал Годен, поскольку держал их жалованье у себя) угрожали сойти с судна при первой возможности. К счастью, не без помощи Лакондамина, конфликт удалось притушить. На Мартинике сделали двухнедельную остановку: команде следовало привыкнуть к местному тропическому климату и развеяться. Пьер Буге, тяжело перенесший морское путешествие, с интересом посетил плантации кофе и сахарного тростника. Тростник тут был традиционной культурой, а вот кофе только-только начали выращивать на Карибах, чтобы удовлетворить растущий спрос на этот напиток.

Вид на кофейную плантацию в Суринаме, Willem de Klerk, 1829 - 1876, https://www.rijksmuseum.nl/
Вид на кофейную плантацию в Суринаме, Willem de Klerk, 1829 — 1876, https://www.rijksmuseum.nl/

Про кофе

С кофе на Мартинике связана чудесная история импортозамещения. В 1720-е годы офицер Габриель де Киле загорелся идеей создать французские кофейные плантации на Мартинике. Он знал, что голландцы выращивают кофе в Индонезии, так что решил, что климат Мартиники будет благоприятным для растений. Достать саженцы было непросто: он чуть ли не украл их в ботаническом саду. Но в 1726 г., всего за 10 лет до того, как на Мартинику прибыли Луи Годен и компания, был собран первый урожай зерен. Так что французские ученые как раз увидели начало американского кофе.

Годен, по словам очевидцев, в крайне неучтивой манере затребовал денег у интенданта Мартиники. Последовал скандал, и Годен распорядился немедленно покинуть остров. Лакондамин в этот момент лежал с приступом желтой лихорадки.

Он вспоминал:

«мне пустили кровь, почистили желудок, напичкали лекарствами и в таком виде погрузили на корабль».

В этот раз (как и в последующие) ему повезло выжить и оправиться. Удивительной силы был человек. Любопытный факт: Лакондамин полагал, что заразился “желтой лихорадкой” после дружеской попойки со знакомым офицером, случайно встретившемся ему на острове. Тот почувствовал симптомы болезни на несколько дней раньше ученого. «Желтый Джек» (или “черная рвота», как ее называли испанцы) был страшной болезнью. От нее порой погибало до трети заболевших: тем больше, чем в более стесненных обстоятельствах жили люди. Сейчас в знаем: лихорадка передается через укусы комаров, как малярия. Так что товарищ Лакондамина был ни при чем. Просто им обоим не повезло быть укушенными.  Итак, «Портофе» держал курс на остров Эспаньола, в его французскую часть Сан Доминго.

Про географию

Фрагмент карты Карибского региона
Фрагмент карты Карибского региона

Давайте немного разберемся с местностью: где находится то самое, Перу и почему надо было сначала добираться на какую-то Эспаньолу? Представим место, где стыкуются континенты Северной и Южной Америки: это бассейн Карибского моря. С запада оно ограничено береговой линией Мексики, Панамы, Коста-Рики (в те времена, о которых мы говорим это все — вице-королевство Новая Испания). С юга — вице-королевством Перу (это сегодняшние Колумбия и Венесуэла), а с востока — Карибскими (или Антильскими) островами. Именно сюда когда-то высадился Колумб. Здесь острова: Куба, Ямайка, и Эспаньола (нам она более известна как Доминикана или Гаити). Именно здесь разбойничал бы Джек Воробей, если б существовал взаправду.

Колониальные владения Франции. Нас интересует то, что помечено зеленым (до 1763 года). Википедия.
Колониальные владения Франции. Нас интересует то, что помечено зеленым (до 1763 года). Википедия.

Франция была третьим после Испании и Португалии колонизатором (казалось бы, где все это теперь?). Ее владения в современной Канаде (Новая Франция) были велики. Вспомните любовно-приключенческий роман «Анжелика в Новом Свете». Главная героиня борется за любовь и жизнь в Новой Франции за 60 лет до нашей истории. В Южной Америке у Франции есть небольшая Французская Гвиана (со столицей Кайенной — именно оттуда кайенский перец), а на Карибах острова Мартиника, Тортуга и Эспаньола. Последний (он же остров Гаити, он же Доминикана), хотели себе и Испания, колонизировавшая его, и Англия, и Франция. К концу XVII века половина Эспаньолы принадлежала испанцам, половина — французам. Именно французская территория острова и была конечной точкой назначения для «Портофе». Для входа на испанские территории надо было пересесть на испанский корабль. В целях секретности и безопасности.

Обратите внимание на "деление" острова Эспаньола пополам. Карта Карибского региона, 1727 г., https://www.rijksmuseum.nl/
Обратите внимание на «деление» острова Эспаньола пополам. Карта Карибского региона, 1727 г., https://www.rijksmuseum.nl/

Эспаньола не случайно всплывает в каждом первом пиратском романе. Это богатое место, где сахар и кофе, ром и соблазны, рабы и пираты варятся в одном котле. И все очень дорого. Правда, пиратство уже начало приходить в упадок (войны приутихли, патенты на это ремесло временно не выдавались и честные каперы стали превращаться в обычных разбойников, с которыми жестко расправлялась регулярная армия).

По плану генерал-губернатор испанской части острова должен был предоставить путешественникам судно, которое сможет доставить их в Перу. Но, увы, у испанцев не нашлось корабля достаточных размеров (кто-то взял слишком много багажа), поэтому пришлось ждать французское торговое судно, которое, так и быть, в качестве исключения, сможет доставить ученых к пункту назначения.

Почему нельзя было воспользоваться «Портофе», на котором группа прибыла из Франции? Да потому что его уже не было на острове. «Портофе» должен был доставить ученых только до Порт-о-Пренса. Дальше у капитана были свои планы и свой маршрут: это был последний рейс флейта на службе французской короне. К тому же, капитан Мешин за время путешествия начал испытывать к мсье Годену личную неприязнь. Бывает.

Пока шла переписка между официальными лицами и ждали новый корабль, власти должны были обеспечивать ученых всем необходимым: ночлегом, питанием и рабами.

Свободные Доминиканцы, Августин Брюне, 1770е, Yale Center for British Art
Свободные Доминиканцы, Августин Брюне, 1770е, Yale Center for British Art

О рабах

Любопытные подробности, о рабах. Во Франции, в отличие от колоний, рабовладение было запрещено. Это означало, что формально любой раб, привезенный хозяином в Старый Свет, становился свободным. Путешественники часто приобретали рабов на Эспаньоле и, при возвращении в Европу, продавали их там же. Или давали вольную. Раб Пьера Буге (фактически он будет работать его личным помощником следующие восемь лет) получит ценнейший опыт землемерных и астрономических работ и, обретя свободу, займет престижную должность королевского землемера на Эспаньоле. Такая вот карьерная лестница. Когда я копала эту историю, то полагала, что раб — это непременно чернокожий, привезенный из Африки. Но это совсем необязательно. Вот что пишет голландец Александр Эксквемелин, за 60 лет до нашей истории служивший врачом по контракту с Французской Вест-Индской торговой компанией:

«…Компании не повезло….(она) была вынуждена отозвать своих агентов и приказала им продать все, что у нее было, а торговлю свернуть. Все слуги Компании были проданы, кто за двадцать, кто за тридцать реалов. Меня также продали, потому что я был слугой Компании, как назло, имел несчастье попасть к самой отменной шельме на всем острове».

Надо сказать, что власти Сан Доминго (как и власти Мартиники до них) были не в восторге от того, как вел себя руководитель научной экспедиции (международного имиджевого проекта, между прочим). Помимо очевидной разобщенности команды: все участники жили в разных домах и коротали время в компании друзей по своему вкусу, Луи Годен жил на скандально широкую ногу.

По слухам, он стал завсегдатаем дорогой куртизанки по имени Гузанн. Отказывая товарищам в деньгах на самые простые надобности вроде чулок и шляп, он требовал от экспедиционного художника Моранвилля (без оплаты, разумеется) написать портрет этой сомнительной дамы и ее хозяйки, а еще, как говорили, приобрел ей в подарок бриллиант на 3000 ливров казенных денег. Конечно, сам Луи Годен этот эпизод с бриллиантом отрицал: мол, его увидели в трактире с большой суммой, когда он расплачивался за гостиницу для товарищей, однако впечатление о себе в глазах общества он испортил. Казалось бы: если начальник такой самодур и все это понимают, почему его не привели в чувство крепким словом? Потому что никому не хотелось оказаться без денег и документов на острове, где тебя могут продать в рабство за долг в пару реалов.

 Букеты Сан-Доминго, L. F. Labrousse. середина 18 века, https://collections.lacma.org/
Букеты Сан-Доминго, L. F. Labrousse. середина 18 века, https://collections.lacma.org/

 Интендант колонии писал о Годене:

«Он очень уж много денег берет в Южную Америку и здесь тратит баснословные суммы. Если ученые скоро не уедут, они могут оказаться в неприятной ситуации».

За три месяца ожидания судна интендант, по его словам, потратил на содержание экспедиции 30 000 ливров, тогда как казна возместила ему только 15 000, то есть, половину. Впрочем, слова бюджетника о расходах, возможно, стоит делить на десять. 15 000 ливров — годовой бюджет экспедиции. От разорения ученых спас корабль «Ватур»: на него перегрузили имущество, оборудование, ученых мужей и их помощников, чтобы с опозданием в три месяца от условленного срока прибыть в Картахену де Лас Индиас (Картахену Индийскую): порт на северном побережье Южной Америки — туда, где французов будут ждать “молодые способные астрономы”, сопровождающие миссию по распоряжению Филиппа V.

Бригантина в спокойном море, Джон Кливли, 1752, National Maritime Museum, Greenwich, London, Macpherson Collection
Бригантина в спокойном море, Джон Кливли, 1752, National Maritime Museum, Greenwich, London, Macpherson Collection

Молодыми способными астрономами были Антонио де Ульоа и Хорхе Хуан и Сантасилья. Я про них уже упоминала: им было слегка за двадцать, но они получили лучшее образование из возможных и оба успели отличиться на море. Поэтому из предосторожности в Новый Свет они отправились на разных судах, в составе эскадры вновь назначенного вице-короля Перу: маркиза де Вильяграсии.

Портрет нового вице-короля Перу: Хосе Антонио де Мендоса Каманьо и Сотомайор, Маркиза де Вильяграсиа, худ. Кристобаль де Агилар
Портрет нового вице-короля Перу: Хосе Антонио де Мендоса Каманьо и Сотомайор, Маркиза де Вильяграсиа, худ. Кристобаль де Агилар

9 июля 1735 года эскадра Вильяграсии прибыла в Картахену. Новый властитель отправился по суше обозревать свои владения, а заодно хорошенько знакомиться с руководителями на местах. Очень мудрое решение, учитывая сложность логистики и скорость почты. Гораздо быстрее и эффективнее раз и навсегда показать, кто тут хозяин, и как его гнева следует опасаться, чем впоследствии устраивать бокс по переписке с каждым отдельно взятым местным начальником.

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

Карта района Картахены Индийской , 1741, аноним, 1741, https://www.rijksmuseum.nl/
Карта района Картахены Индийской , 1741, аноним, 1741, https://www.rijksmuseum.nl/

16 ноября 1735 года «Ватур» встал на якорь у Картахены, и участники экспедиции впервые собрались вместе. Хуан и Ульоа неплохо владели французским и хотели произвести хорошее впечатление на лучших ученых Парижа.

Каково же было их удивление, когда оказалось, что ученые — по большей части не те, на которых выписаны паспорта, что не очень понятно как там со знаниями, но с дисциплиной в этой команде плохо: Буге и Лакондамин не разговаривали с Годеном, а тот писал записки, когда хотел им что-то сообщить. Настроение французов было подавленным, и они не сразу приняли новых товарищей. Им казалось, что молодые офицеры “выпячивают свою любовь к физике, как иные выставляют напоказ модное украшение”.

Тем не менее, Ульоа и Хуан взяли себя в руки, постарались быть учтивыми и дружелюбными и приложить все усилия, чтобы наладить коммуникацию в группе. До Кито, где планировали начать работы, оставались месяцы пути.

Итак, поскольку Панамского канала еще не существовало, чтобы из Атлантического попасть в Тихий океан, ученым требовалось пересечь Панамский перешеек. Это делалось частично по рекам на каноэ, частично на мулах. Такая сложная логистика означала некоторые задержки: поиск лошадей, провожатых, лодок и прочие дорожные хлопоты. Ожидать, когда все будет готово к поездке Луи Годену с товарищами пришлось в городе Портобело.

Ученые свои впечатления о Портобело описывали как “очень плохо за очень дорого”. И, судя по тем панорамам, которые можно увидеть на Google картах, это до сих пор справедливо. Дело в том, что Портобело (прекрасный порт) был город-ярмарка.

Про карибские ярмарки

Забавный факт: Испания владела обширными колониями в Филиппинах. Наиболее популярный путь доставки товаров (пряностей, фарфора, слоновой кости, тканей) проходил через современную Панаму. Из Манилы, столицы Филиппин, галеоны раз или два раза в год отправлялись в сторону Южной Америки, на восток.

Манильская шаль начала XX в. (мантоны, которые в начале XX века стали частью испанского национального костюма, как раз шли по пути Китай-Манила-Акапулько-Веракрус-Кадис)
Манильская шаль начала XX в. (мантоны, которые в начале XX века стали частью испанского национального костюма, как раз шли по пути Китай-Манила-Акапулько-Веракрус-Кадис)

Товары оказывались в Акапулько (кстати, именно оттуда, как это ни странно, осуществлялось управления Филиппинами), после по суше перевозились на Атлантическое побережье в Портобело или Веракрус, чтобы на других галеонах пересечь Атлантический океан и оказаться в Испании. Также в Портобело оказывалось золото, добытое в Новой Испании. То есть, товары и золото оказывались в одном месте в одно время.

Маршруты манильских галеонов и дорога с серебром в Испанию (белым цветом). Википедия.
Маршруты манильских галеонов и дорога с серебром в Испанию (белым цветом). Википедия.

В Портобело и Панаме устраивались невероятные по размаху ярмарки: это была единственная возможность для жителя Латинской Америки купить что-то, не производимое на материке. Торговали не только тем, что привозили сФилиппин. Еще была легальная и контрабандная торговля тем, что привозили английские капитаны. Можно было купить специи, чай, кофе, лекарства, инструменты, книги, предметы искусства, драгоценные ткани и музыкальные инструменты. Ярмарка длилась от полутора до двух месяцев, потом купцы разъезжались, и город пустел.

Ярмарка в Портобело, 1720, A. Aveline, Colección John Carter Brown Library
Ярмарка в Портобело, 1720, A. Aveline, Colección John Carter Brown Library

Вот, что пишет Александр Эксвемелин (голландский врач, ходивший с пиратами в 17 веке):

«Почва в этих местах постоянно выделяет испарения, и поэтому климат не очень-то здоровый, и купцы охотнее живут в Панаме, хотя их склады находятся в Пуэрто-Бельо и там работают их служащие».

Собственно, жители Портобелло, подобно жителям курортных городов, зарабатывали исключительно в сезон: три четверти домов стояли пустыми, ожидая постояльцев во время ярмарки. К сожалению, местный климат, очень жаркий и очень влажный, порождающий эпидемии, был непригоден для земледелия и других занятий. Неудивительно, что французские ученые, оказавшиеся в Портобело в несезон, были неприятно удивлены. Мокро, жарко, малярийно и очень дорого.

В целом, Портобело и Веракрус были не единственными городами-ярмарками. Еще была ярмарка в Картахене де лас Индиас (Картахене Индийской) и в Акапулько. Но количество городов, где разрешалась торговля, строго ограничивалось, так что жители колоний крайне нуждались в товарах народного потребления и были готовы приобретать их на свое серебро и золото из копей Перу. Испанские власти же крайне нервно относились к незваным гостям (например, англичанам), которые пытались без разрешения торговать с населением. В общем, контрабандистов они не любили, мягко говоря. 

Картина Morgan at Porto Bello: Pyle, Howard (December 1888). "Buccaneers and Marooners of the Spanish Main". Harper's Magazine
Картина Morgan at Porto Bello: Pyle, Howard (December 1888). «Buccaneers and Marooners of the Spanish Main». Harper’s Magazine

Про пиратов: Пираты были охочи до жирных и богатых ярмарочных городов, так что частенько разоряли их в 16 и 17 веках. В частности, сюда ходили Дрейк и Морган: грабили жителей, пытали их, вставляя горящие фитили между пальцев и делали другие мерзкие вещи (подробности пиратских допросов есть у Эксвемелина, а я о них умолчу). Матери Панамы и Портобело еще в 50 е годы XX века пугали ребятишек чудовищным «дон Драпе» (Френсисом Дрейком), который их утащит.

А вот вам история про контрабанду

Французский бриг «Ватур», на котором экспедиция добрались до Портобело, должен был основную часть багажа и инструмента передать на склады Картахены Индийской, и все произошло бы именно так, если бы капитан «Ватура» не был пойман береговой охраной при попытке торговать драгоценными тканями и ювелирными изделиями в одном из местных прибрежных поселений, что было одним из наиболее тяжких возможных преступлений.

Разумеется, капитан, получивший указание разведать торговый маршрут от правительства Франции, все отрицал, утверждая, что это вообще не ткани, а личные вещи господ ученых. Он просто портом ошибся. Капитана отпустили, но осадочек остался. Весть об иностранцах-аферистах разнеслась по аудиенсии Кито задолго до того, как сами ученые туда добрались.

Испанские колонии — устройство

Желтым отмечены испанские территории к 1800-му году. Википедия.
Желтым отмечены испанские территории к 1800-му году. Википедия.

Поскольку прозвучало непонятное слово “аудиенсия”, давайте углубимся немного в устройство колониальной Испании. Как мы уже говорили, испанские владения в Новом Свете (за редкими исключениями) делились на вице-королевства. Большую часть территории Северной и Южной Америки занимали вице-королевства: Новая Испания (Мексика), Перу, Новая Гранада (ее периодически расформировывали, как территориальную единицу).

Вице-королевство Перу. Темно-зеленый в 1542, светло-зеленый к 1810.Википедия.
Вице-королевство Перу. Темно-зеленый в 1542, светло-зеленый к 1810.Википедия.

Самым главным в вице-королевстве был вице-король. На несколько лет он становился наместником, единоличным представителем короля в колониях, ему было поручено вершить правосудие, распоряжаться казной и руководить обращением в святую веру. Вице-короли всегда прибывали из метрополии и возвращались туда же. Чтобы, обладая почти неограниченной властью, не иметь соблазна построить свое маленькое государство. И новый вице-король Перу, маркиз де Вильяграсиа, как мы помним, прибыл в Картахену Индийскую вместе с офицерами Хуаном и Ульоа. Далее он по суше отправился в Лиму — столицу своих владений. Далеко ли это? Сейчас, по дорогам, 3,5 тысячи километров. То, что раньше было вице-королевством Перу сейчас включает в себя страны: Перу, Чили, Эквадор, Колумбию, Боливию, Парагвай, Уругвай и Аргентину. В указах того времени встречается формулировка: “и распространяется далее на все известные и еще не известные территории”. Управлять такой махиной из центра — просто немыслимо. В помощь вице-королю давались институты власти под названиям аудиенсии.

Желтый - путь от Картахены в Лиму по суше. Розовый - по морю.
Желтый — путь от Картахены в Лиму по суше. Розовый — по морю.

Аудиенсией называлась как высшая судебная инстанция на заданной территории, так и сама территория (например Аудиенсия Кито). Во главе аудиенсии стоял президент (presidente, что аналогично скорее председателю). Он работал с целой командой избранных и достойных государственных мужей, но, фактически, являлся самым влиятельным лицом на территории, ибо до Бога высоко, до царя, то есть, вице-короля далеко и, вообще, они временные.

Сельская жизнь в коррхимьенто Кито. Округ (коррехимьенто) Кито. Из отчета Хуана и Ульоа, 1748
Сельская жизнь в коррхимьенто Кито. Округ (коррехимьенто) Кито. Из отчета Хуана и Ульоа, 1748

Чуть ниже по статусу стояли коррехидоры, по-нашему исправники: они надзирали за судебной и муниципальной властью на территориях, где, в основном, проживало коренное население: собирали налоги, назначали трудовую повинность. В некоторых случаях президент являлся коррехидором (и вице-королем) одновременно.

О разделении в пути

Новый серьезный конфликт в команде случился в порту Манты (город на западном побережье Южной Америки). Лакондамин и Буге предлагали там задержаться для осмотра территории на предмет удобства градусных измерений и для определения координат береговой линии: согласно обязательству перед королем Испании ученые должны были это делать. Годен же, то ли не хотел тратить время, то ли не хотел уступать коллегам.

В итоге, как передает очевидец:

“Мсье Лакондамин заявил перед всеми, что если никто не хочет высаживаться в Манте, то они с мсье Буге сойдут там одни”.

Так и произошло. Лакондамин и Буге высадились, а Годен не стал их ждать и отчалил, бросив своих непокорных товарищей. Свой резон у него был: он спешил попасть в порт Гуякиль к лунному затмению, чтобы точно определить долготу этого крупного порта.

Итак, Буге и Лакондамин остались вдвоем в испанском поселении. Впрочем, их ждал почтительный и теплый прием. Настолько теплый, что астрономы задержались там на два месяца: в марте 1736 года, они отнаблюдали лунное затмение и определили долготу Манты, о чем оставили памятную табличку, высеченную на камне. Кстати, Годен, который спешил в Гуякиль для того же самого, не преуспел: небо было затянуто тучами.

Памятный камень близ Манты в деревушке Палмар. Из отчетов Лакондамина.
Памятный камень близ Манты в деревушке Палмар. Из отчетов Лакондамина.

Помните, мы говорили, что в начале XVIII века вопрос определения долготы на море стоял настолько остро, что был объявлен конкурс на долготный приз за изобретение точного хронометра? На суше ту самую долготу можно отыскать, наблюдая на разных долготах одно и то же событие (лунное затмение, в данном случае) и определяя местное время, в которое оно произошло. Хорошо все же, что Лакондамин и Буге не послушались руководителя. Так бы и Манта осталась без координат.

 О флоре и фауне Перу

Кроме рекогносцировки, Лакондамин и Буге смело окунулись в наблюдения за окружающим. Они пробовали чудесные фрукты, записывали заметки о кастах и расах (в колониях Испании много внимания уделялось чистоте и качеству крови), воздавали должное маисовым лепешкам и зеленым бананам, спелой чиримойе (это фрукт такой, на вкус как клубничное мороженое) и хвостатому кую (до того, как конкистадоры привезли куриц, любимым мясом индейцев была морская свинка).

На картине Висенте Альбана (1773, музей Америки, Мадрид) представлены все дары природы: чиримойя (D), клубника, авокадо, капуле (местные ягоды) и прекрасная Япанга в наряде, какой "носят эти женщины, доставляющие удовольствия".
На картине Висенте Альбана (1773, музей Америки, Мадрид) представлены все дары природы: чиримойя (D), клубника, авокадо, капуле (местные ягоды) и прекрасная Япанга в наряде, какой «носят эти женщины, доставляющие удовольствия».

Местные жители щедро делились советами по выживанию в джунглях и вовремя: гамаки становились убежищем то для гремучих змей, то для гигантских пауков размером с яйцо, то для страшных игуан — «жутких рептилий, однако весьма вкусных в приготовленном виде» (это я уже Буге цитирую).

Буге подробно описывает в дневнике все свои впечатления. Ученых поразило невероятное разнообразие флоры: оливки, акация, папоротник соседствовали с кактусами, алоэ и мангровыми зарослями. В чаще леса находили каллофилум (автор особо подчеркнул, что эта древесина подходит для мачт кораблей). Любопытно, что, описывая животных, Буге упоминает львов (на самом деле, это пума) и тигров (ягуаров).

Жареная морская свинка. Фото из Википедии. До сих пор специалитет Эквадора.
Жареная морская свинка. Фото из Википедии. До сих пор специалитет Эквадора.

Тут надо оговориться, что ученые были немножко блогерами своего времени: они писали дневники и письма, с явным осознанием того, что те потом будут зачитываться в салонах, цитироваться и служить пищей для светских бесед. 

Под впечатлением от этой экспедиции Перу вошло в моду в Париже, и появились “Альзира” Вольтера и “Письма Перуанки” Франсуазы де Графиньи. Поэтому, не исключено, что драматизация событий — в некотором роде художественный прием, чтобы сделать рассказ более живым и интересным.

Как известно, продаются секс и кровь. Первое продавалось (покупалось) на Эспаньоле, а кровавых подробностей ученые начинали накидывать уже в джунглях (возможно, за недостатком прекрасных дам).

Упоминая все чудеса тропического побережья, следует заметить, что европейцам было непросто привыкнуть к местному климату: стояла влажная 37-градусная жара, в почве и деревьях копошились кусачие насекомые, и вскоре каждого из них начали посещать первые приступы малярийной лихорадки. Буге, чувствуя себя неважно, решил, наконец, воссоединиться с Годеном. Он отправился догонять коллег по простому пути в Гуякиль (догонять — это по бездорожью полузатопленного берега в сезон дождей). Они разминулись на три дня: Годен только-только выдвинулся в Кито. А так он два месяца проторчал в Гуякиле ожидая, пока дожди прекратятся и дороги подсохнут.

О прямой дороге

Путь Буге - розовый, Лакондамина - желтый.
Путь Буге — розовый, Лакондамина — желтый.

А Лакондамин решил пойти в Кито напрямик, вдоль русла реки Эсмеральдас. Если вы сейчас откроете карту, то увидите, что это действительно прямой путь. Более-менее.

Ученый рассуждал так: река туда течет. Значит, можно идти по берегу. Как его ни отговаривали — настоял на своем. Отправился с рабом, слугой и индейскими провожатыми. Вновь явив миру свою незаурядную смелость. Где-то на середине пути провожатые, взяв плату вперед, растворились в джунглях, и Лакондамин остался один (с рабом, слугой и кофрами с инструментами). Вот что он писал про свой путь:

Лес такой густой, что дорогу приходилось буквально прорубать. Я шел с компасом в одной руке и мачете в другой. Чаще пешком, чем верхом. Дождь лил каждый день. Мне также пришлось нести на себе все инструменты, в том числе квадрант, с которыми с трудом раньше справлялись двое носильщиков. Восемь дней я блуждал по лесу совсем один, брошенный проводниками, из еды имея только бананы и фрукты, которые удавалось сорвать. Одолевавшие меня приступы лихорадки лечил воздержанием от еды и растениями, которые мне подсказывал здравый смысл.

Где-то по ходу этих перемещений он открыл для европейцев каучук (заметив, что млечный сок, который индейцы добывают из некоторых растений образует плотные шарики) и описал кору правильного хинного дерева. Что хинин лечит лихорадку — было известно. Но некоторые сорта хины помогают, а некоторые — нет. Лакондамину повезло. Через неделю пути он (с рабом и слугами) набрел на индейское поселение, где смог купить мулов и нанять проводников до города. Точнее, взять их под залог собственных вещей.

Не надо поступать, как Лакондамин. Не надо ходить в джунглях вдоль рек. Они извилистые, берега там густо заросшие, а попытка “срезать” изгиб приводит к тому, что путешественники теряют направление. История Исабель Дезодоне (20 лет спустя), полковника Фоссета (100 лет спустя) и Йоси Гинсберга 150 лет спустя снова и снова это доказывает.

Кито в XIX веке, Rafael Salas, Википедия.
Кито в XIX веке, Rafael Salas, Википедия.

Итак, в июне 1736 года, спустя год и два месяца с начала пути, экспедиция, наконец, достигла своего пункта назначения — города Кито. Казалось бы, теперь все должно было стать хорошо? Но не совсем…

 Предыдущие части этого цикла:

  1. О форме Земли: тыква или дыня?

  2. Как набрать команду к экватору?

  3. Планирование экспедиции.

  4. Приборы и инструменты.


ссылка на оригинал статьи https://habr.com/ru/post/646101/

Связный список на Rust в стиле С/C++

Может ли безопасный и стабильный Rust противопоставить что-то аккумулированному опыту многих десятилетий от Си и C++? Вот, например, типобезопасный список на Си:

int *nums = NULL; int sum = 0; *(nums = ll_new(nums)) = 5; *(nums = ll_new(nums)) = 10;  ll_foreach(nums, num) {     sum += *num; } /* sum == 15 */

СД; НО: не может. Придется встать на путь, полный опасностей и приключений.

Трудности графо-мании

Во времена, когда я изучал Си и С++, программирование списков и прочих графов было весьма популярной задачей. Судя по всему для изучающих Rust эта тема весьма актуальна, если не сказать — горяча. Рассмотрим несколько цитат.

If you want to create data structures which can be modified during runtime, a possible solution could lead into tree or graph like structures. Writing tree structures in Rust is no trivial problem.

Idiomatic tree and graph like structures in Rust,

Автор демонстрирует, что для новоприбывших в Rust устройство ребер графов традиционным способом выглядит пугающе:

В качестве решения предлагается поместить все вершины графа в «арену» и для моделирования ребер использовать целочисленные идентификаторы вершин. Идем дальше.

Частая ошибка пробующих ржавчину новичков — пробовать написать свой двусвязный список, т.к. в большинстве языков это довольно простая задача. Быстро оказывается что сделать это в ржавчине в лоб не так-то и просто из-за модели работы с памятью

Комментарий от ozkriff

ozkriff приводит две ссылки, одна из которых, КМК, особенно интересна:

I fairly frequently get asked how to implement a linked list in Rust. The answer honestly depends on what your requirements are, and it’s obviously not super easy to answer the question on the spot. As such I’ve decided to write this book to comprehensively answer the question once and for all.

Learn Rust With Entirely Too Many Linked Lists

Занятный вариант изучения Rust на практических примерах в виде связных списков, в принципе, почему нет? Ну и, наконец:

Просто все интуитивно знают, что «связный список» — классическая задача на языках с ГЦ, и идут автоматически пытаться её реализовать в раст. Это неправильный подход.

Комментарий от PsyHaSTe

Cкладывается ощущение, что опытные разработчики Rust тему списков не любят. А за что ее любить? Ведь и сам Бьёрн Страуструп занял такую позицию:

And, yes, my recomendation is to use std::vector by default. More generally, use a contiguous representation unless there is a good reason not to.

Are lists evil? — Bjarne Stroustrup

Тем-не менее, сейчас состоится🎥 разбор примера программирования списка на Rust в стиле, подобном C/C++.

Попытка не пытка

Начнем с простого примера для подражания на C:

struct Node {   int data;   struct Node *next; }

Такую структуру вполне можно определить и на Rust:

struct Node<'a> {     data: i32,     next: &'a Node<'a>, }

Определить можно, а создать первый и последний элементы списка нельзя — при создании структуры требуется явная инициализация всех полей (отсюда проблема с первым элементом, где есть ссылка на следующий), а значения null для ссылок нет (что порождает проблему с последним элементом, который ссылается в никуда).

«Идиоматический» подход подразумевает использование умных указателей и ряда других уловок, типа Option. Посмотрим на представителя семейства умных указателей Box:

pub struct Box< T: ?Sized, A: Allocator = Global,   ...     impl<T> Box<T> {   ...   pub fn new(x: T) -> Self {     box x   }   ...

Что такое box x? Попробуем:

struct MyBox<T>(*mut T);  impl<T> MyBox<T> {     pub fn new(x: T) -> Self {         box x     } }

Результат:

> error[E0658]: box expression syntax is experimental; you can call `Box::new` instead > ... > 4 |     pub fn new(x: T) -> Self { >   |                         ---- expected `MyBox<T>` because of return type > 5 |         box x >   |         ^^^^^ expected struct `MyBox`, found struct `Box`

Ясно — ключевое слово box все еще является экспериментальным и делает исключительно Box. Умные указатели надо, конечно, рассматривать отдельной статьей, но один любопытный момент, обнаруженный в процессе исследования, вынес в Приложение.

Ладно, мы и так уже знаем, как работать с кучей — будет немного опасно, зато стабильно. Поехали.

Список в стиле Си

У гиков Си-версия «Linked List Traversal» выглядит так:

int main() {     struct Node* head = NULL;     struct Node* second = NULL;     struct Node* third = NULL;      // allocate 3 nodes in the heap     head = (struct Node*)malloc(sizeof(struct Node));     second = (struct Node*)malloc(sizeof(struct Node));     third = (struct Node*)malloc(sizeof(struct Node));      head->data = 1; // assign data in first node     head->next = second; // Link first node with second      second->data = 2; // assign data to second node     second->next = third;      third->data = 3; // assign data to third node     third->next = NULL;      printList(head);      return 0; }

Можно ли такое сделать на Rust? Да запросто:

unsafe fn unsafe_main() {      let first: *mut Node = ptr::null_mut();     let second: *mut Node = ptr::null_mut();     let third: *mut Node = ptr::null_mut();      // allocate 3 nodes in the heap     let third = alloc(Layout::new::<Node>()) as *mut Node;     let second = alloc(Layout::new::<Node>()) as *mut Node;     let head = alloc(Layout::new::<Node>()) as *mut Node;      (*head).data = 1; // assign data in first node     (*head).next = second; // Link first node with second      (*second).data = 2; // assign data to second node     (*second).next = third;      (*third).data = 3; // assign data to third node     (*third).next = ptr::null_mut();      print_list(head);     free_list(head); }

Гики, правда, забыли освободить память, этот момент повторить не удалось.

В принципе, особой разницы нет, за исключением того, что надо писать unsafe. Все, с С разобрались 🎥.

Список в стиле C++

В Rust есть прекрасные возможности в виде системы обобщенных типов (список будет работать для всех типов), автоматического вызова drop() (не надо думать про вызов free_list()), а также контроля времен жизни (нелья поместить в список короткоживущую ссылку и проч.). Задействуем же все это и рассмотрим некоторые детали реализации.

Список построен на «сырых указателях» (raw pointers):

pub struct Item<T> {     data: T,     next: *const Item<T>, }  pub struct List<T> {     head: *const Item<T>, }

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

Для итерирования по списку будем использовать замыкание:

pub fn for_each<F: FnMut(&T)>(&self, mut f: F) {     let mut cur = self.head;     while !cur.is_null() {         unsafe {             f(&(*cur).data);             cur = (*cur).next;         }     } }

  • Появился небольшой блок unsafe, посвященный разыменованию сырых указателей

push() выделяет память и перемещает туда переданное значение:

    pub fn push(&mut self, value: T) {         let pitem;         unsafe {             pitem = alloc(Layout::new::<Item<T>>()) as *mut Item<T>;             std::ptr::write(&mut (*pitem).data, value);             (*(pitem)).next = self.head;         }         self.head = pitem;     }

  • alloc() и write() являются unsafe, как и еще одно разыменование
  • В недрах write() происходит «забывание» value, так что деструктор drop() для этого значения не вызывается

Серия тестов вынесена в свой модуль, чудесная песочница позволяет запускать тесты отдельно от запуска main:

#[cfg(test)] mod tests {     use super::*;     ...

main(), однако, тоже сделал — было интересно визуально проконтролировать последовательность вызова деструкторов:

... // List of Points {     let mut ls = List::<Point>::new();     ls.push(Point { x: 1, y: 2 });     ls.push(Point { x: 10, y: 20 });     ls.pop();             ls.push(Point { x: 100, y: 200 }); } ...

Последовательностью вызовов деструкторов удовлетворен:

Dropping Point { x: 10, y: 20 }... Dropping List<playground::Point>... Dropping Point { x: 100, y: 200 }... Dropping Point { x: 1, y: 2 }... ...

В комментариях, на мой взгляд, тоже интересно, хотя и не компилируется.

Первый пример: пытаемся поместить короткоживущую ссылку в долгоживущий список ссылок (не компилируется):

    // Attempt to put a short-lived reference to a long-lived list     {         let mut ls = List::<&String>::new();         let rstr: &String;         let s = String::from("String 1");         ls.push(&s); //  error[E0597]: `s` does not live long enough         rstr = ls.pop();         dbg!(rstr);     }

Второй пример: пытаемся записать ссылку на короткоживущее значение в ссылку на долгоживущее (не компилируется):

    // Attempt to pop a reference to a short-lived value to a long-lived value reference     {         let rstr: &String;         {             let s = String::from("String 1");             let mut ls = List::<&String>::new();             ls.push(&s); // error[E0597]: `s` does not live long enough             rstr = ls.pop();         }         dbg!(rstr);     }

   Compiling playground v0.0.1 (/playground) error[E0597]: `s` does not live long enough    --> src/main.rs:181:21     | 181 |             ls.push(&s); // error[E0597]: `s` does not live long enough     |                     ^^ borrowed value does not live long enough 182 |             rstr = ls.pop(); 183 |         }     |         - `s` dropped here while still borrowed 184 |         dbg!(rstr);     |              ---- borrow later used here

Для разнообразия третий пример, который показывает, что компилятор могуч, но не всемогущ (код компилируется и паникует):

    // Pop from an empty list to a long-lived reference     {         let rstr: &String;         {             let mut ls = List::<&String>::new();             rstr = ls.pop(); // thread 'main' panicked at 'assertion failed: !cur.is_null()', src/main.rs:50:9         }         dbg!(rstr);     }

Некоторые размышления

Склонен согласиться с тем, что Rust занимает промежуточное положение между C и C++, в качестве метрики для сравнения можно рассмотреть количество ключевых слов:

┌───────────────────────────────────────────────────────────────────────────────────────────┐ │                                                                                    ...... │ │                                                                                    ...... │ │                                                                             ...... ...... │ │                                                                             ...... ...... │ │                                                                      ...... ...... ...... │ │                                                                      ...... ...... ...... │ │                                                                      ...... ...... ...... │ │                                                                      ...... ...... ...... │ │                                                                      ...... ...... ...... │ │                                                        ...... ...... ...... ...... ...... │ │                                          ...... ...... ...... ...... ...... ...... ...... │ │                                          ...... ...... ...... ...... ...... ...... ...... │ │                            ...... ...... ...... ...... ...... ...... ...... ...... ...... │ │              ...... ...... ...... ...... ...... ...... ...... ...... ...... ...... ...... │ │...... ...... ...... ...... ...... ...... ...... ...... ...... ...... ...... ...... ...... │ │...... ...... ...... ...... ...... ...... ...... ...... ...... ...... ...... ...... ...... │ │..22.. ..25.. ..26.. ..32.. ..35.. ..36.. ..49.. ..51.. ..52.. ..54.. ..89.. .100.. .109.. │ │Lua    Go     Erlang C      Python Ruby   JS     Java   Rust   Dart   Swift  C#     C++    │ └───────────────────────────────────────────────────────────────────────────────────────────┘

Т.е., если рассматривать Rust как «замену», то это скорее «замена» языка C, чем C++. С учетом гарантий безопасности стремление использовать Rust в ядре Linux вместо С мне вполне понятно (впрочем, также понятны и сомнения по этому поводу).

Однако, если сравнивать по другим критериям, то может оказаться, что Rust ближе всего к Go — именно такой тезис я выдвинул в первой части. С точки зрения «гофера» изложенный материал может быть оценен такий образом. Какие проблемы решает Rust?

  • Висячие указатели (dangling reference). В Go неактуально, ввиду автоматического управления памятью
  • GC overhead. В Go проблема имеет место, но не так горяча, как ранее. Кроме того, существуют кардинальные средства решения проблем больших кэшей
  • Data race. Safe Rust guarantees an absence of data races, это очень круто. В Go эта боль весьма сильна, однако, она облегчается инструментами тестирования, которые позволяют ловить существенную часть таких ошибок

И все-таки, есть кое-что…

  • ЭТО заставляет разработчика Go ежедневно страдать
  • В Rust ЭТО делать легко и приятно

Про ЭТО речь впереди🎥.

Приложение. Про box и println!()

В «ночной» версии box прекрасно работает:

#![feature(box_syntax)]  fn type_name<T>(_: T) -> &'static str {     std::any::type_name::<T>() }  fn main() {     let five = box 5;     println!("{}", five);     println!("{}", type_name(five)); // alloc::boxed::Box<i32> }

  • Имя получаемого типа выводится несколько экзотическим образом, но другого способа не нашел
  • Как и обещал компилятор, из box получается только Box

Обнаружил такой нюанс — если заменить println! на dbg!, то получим ошибку:

8  |     let five = box 5;    |         ---- move occurs because `five` has type `Box<i32>`, which does not implement the `Copy` trait 9  |     dbg!("{}", five);    |     ---------------- value moved here 10 |     dbg!("{}", type_name(five)); // alloc::boxed::Box<i32>    |                          ^^^^ value used here after move

С dbg!() все понятно — обернутая «пятерка» передаётся по значению, trait Copy для alloc::boxed::Box не реализован, так что дальнейшее использование переменной five исключено. Но как же тогда работает println!()?! Тут какое-то колдунство (дело-то происходит ночью).

Поиск по исходникам дает такой результат:

println:

macro_rules! println {     () => ($crate::print!("\n"));     ($($arg:tt)*) => ({         $crate::io::_print($crate::format_args_nl!($($arg)*));     }) }

format_args_nl:

    /// Same as `format_args`, but adds a newline in the end.     macro_rules! format_args_nl {         ($fmt:expr) => {{ /* compiler built-in */ }};         ($fmt:expr, $($args:tt)*) => {{ /* compiler built-in */ }};     }

format_args:

    macro_rules! format_args {         ($fmt:expr) => {{ /* compiler built-in */ }};         ($fmt:expr, $($args:tt)*) => {{ /* compiler built-in */ }};     }

В общем, прикольный язык этот Rust — в нем нельзя без ночного шаманства безопасно поместить значение в кучу и также отсутствует возможность форматировать список значений разных типов.

Такие дела.


ссылка на оригинал статьи https://habr.com/ru/post/646105/

HackTheBox разбор ID Exposed. На поиски Сары. Продолжаем разбор лаборатории OSINT (Уровень: Easy)

Здравствуйте, продолжаю цикл статей по разбору OSINT EASY-уровня.

Задача
We are looking for Sara Medson Cruz’s last location, where she left a message. We need to find out what this message is! We only have her email:
saramedsoncruz@gmail.com

В этот раз задачка найти Сару (произносить с еврейским акцентом) по почте saramedsoncruz@gmail.com и по ее последним письмам.Скажу сразу: ищем руками, ботов использовать не будем. Иначе как вы научитесь!?

Собственно, вся информация, что у нас есть — это электронная почта и некая информация от самой Сары.В этот раз я попробую публиковать не уже готовые статьи с описанием проделанной работы, а попытаюсь изложить ход своих мыслей. Рассказать то, как я пришел к конкретному заключению.Итак, нам нужно найти Сару. Если у нее Google Mail, значит, она наверняка оставляла отзывы на Google Maps. Спойлер: найдем мы ее не в Одессе. Давайте начнем искать информацию.Спрашиваем у Google следующее: “find location on maps gmail”

https://support.google.com/maps/answer/7326816?hl=en&co=GENIE.Platform%3DAndroid

Так, не отвлекаемся! Нам требуется найти информацию, поэтому пишем в Google
Osint: “найти локацию по имейл”. Но только на английском! Так больше вариантов найти нужное решение.

osint find location using email address

Теперь мы попадаем на видео, где человек показывает как найти ID по почте в коде страницы.Особо впечатлительных прошу не беспокоиться! Выдохните, вдохните! Продолжаем.

Возникает извечный вопрос: все отлично но что же делать дальше? Мы знаем, как найти ID в коде страницы. Но это id страницы учетной записи автора видео, а не Сары Медсон Круз. Но также мы знаем что еще живо Hangouts. Нужно как-то два этих параметра совместить. Но как — пока не понятно.

Мы помним что пользователи учетной записи Google могут поделиться своим местоположением с друзьями. Как же быть, ведь мы к Саре не как не попадем в друзья! А нам как-то требуется посмотреть ее местоположение.
Я не помню как нашел данное решение но оно мне помогло. Кто же знал, что оно окажется на reddit!

Пожалуй на всякий случай сохраню это сюда - вдруг пригодится:
Пожалуй на всякий случай сохраню это сюда — вдруг пригодится:

Цитирую пост с reddit:
Updated Google ID search method by Gmail address (Old method with contacts is fixed)
open
hangouts.google.com on your PC and click on your contacts in the left corner.
Click on create a chat and enter the gmail address you want in the search.
Right-click on the name of the account and select Inspect.
4. In the developer tools find the line with hovercard-oid
5. After this phrase is an ID of 21 digits long, copy this ID
Using Google ID
https://get.google.com/albumarchive/GoogleID — replace GoogleID with the numbers you copied, find your account’s picture album.
https://www.google.com/maps/contrib/GoogleID — replace GoogleID with the numbers you copied, find your Google Maps account.

Перейдем к поиску флага.
Стряхиваем пыль тысячелетий с Hangouts и создаем там встречу с Сарой
Начинаем просматривать код. Нам требуется найти ID.

Ищем hovercard-oid, где находим 117395327982835488254. Он нам как раз и нужен
Ищем hovercard-oid, где находим 117395327982835488254. Он нам как раз и нужен

Заходим по ссылке https://www.google.com/maps/contrib/GoogleID
Вместо GoogleID требуется вписать параметр который мы нашли.
Переходим по сформированной нами ссылке в отзывы.
https://www.google.com/maps/contrib/117395327982835488254

В итоге находим что мы искали
В итоге находим что мы искали
флаг

HTB{i_W4S_D_I_S_c_O_v_3_R_3_D}

На этом все, уважаемые друзья. Данная задачка хоть и считается простой, но она заняла у меня кучу времени. На описание размышлений и действий, а также на придумывание шуточек у меня ушло еще несколько дней. Прошу простить, но писать однообразные статьи мне становиться скучно. Я решил в них добавить немного юмора, чтобы как-то выделится среди более талантливых специалистов

Напоследок для послевкусия OSINT Google and Social Networks Hacks

Великий и ужасный Сергей Сталь
Редактор: Александра Калюжная


ссылка на оригинал статьи https://habr.com/ru/post/646109/