По вашему запросу ничего не найдено :(
Убедитесь, что запрос написан правильно, или посмотрите другие наши статьи:
img
Седьмая часть тут. Поля фиксированной длины - самый простой из описанных в словаре механизмов. Протокол определяет набор полей, какие данные содержит каждое поле и насколько велико каждое поле. Эта информация «встроена» в определение протокола, поэтому каждая реализация построена в соответствии с этими же спецификациями и, следовательно, может взаимодействовать друг с другом. Рисунок 1 иллюстрирует кодирование поля фиксированной длины, используемое в протоколе Open Shortest Path First (OSPF), взятом из RFC2328. Ряд чисел в верхней части рисунка 1 указывает отдельные биты в формате пакета; каждая строка содержит 32 бита информации. Первые 8 битов указывают номер версии, вторые 8 битов всегда имеют номер 5, следующие 16 битов содержат общую длину пакета и так далее Каждое из этих полей дополнительно определяется в спецификации протокола с видом информации, переносимой в поле и как оно закодировано. Например: Поле номера версии кодируется как целое число без знака. Это метаданные, указывающие словарь и грамматику, используемые для этого пакета. Если формат пакета необходимо изменить, номер версии может быть увеличен, что позволяет передатчикам и получателям использовать правильный словарь и грамматику при кодировании и декодировании информации в пакете Число 5 указывает тип пакета в протоколе; это часть словаря, определенного в другом месте в документе стандартов, поэтому он просто вставляется как фиксированное значение на этом рисунке. Этот конкретный пакет является пакетом подтверждения состояния канала (Link State Acknowledgment Packet). Длина пакета кодируется как целое число без знака, указывающее количество октетов (или наборов из 8 битов), содержащихся в полном пакете. Это позволяет размеру пакета варьироваться по длине в зависимости от объема передаваемой информации. Формат поля фиксированной длины имеет несколько преимуществ. Прежде всего, местоположение любого фрагмента информации в пакете будет одинаковым для каждого пакета, что означает, что легко оптимизировать код, предназначенный для кодирования и декодирования информации вокруг формата пакета. Например, обычным способом обработки формата пакета фиксированной длины является создание структуры данных в памяти, точно соответствующей формату пакета; когда пакет считывается с провода, он просто копируется в эту структуру данных. Поля в пакете могут быть прочитаны напрямую. Форматы фиксированной длины имеют тенденцию быть несколько компактными. Метаданные, необходимые для кодирования и декодирования данных, передаются «вне протокола» в форме спецификации протокола. Сами пакеты содержат только значение и никогда не содержат никакой информации о значениях. С другой стороны, форматы фиксированной длины могут тратить много места на буферизацию полей, чтобы они всегда были одинаковой длины. Например, десятичное число 1 может быть представлено одной двоичной цифрой (один бит), тогда как десятичное число 4 требует 3 двоичных цифры (три бита); если поле фиксированной длины должно быть в состоянии представить любое число от 0 до 4, оно должно быть длиной не менее 3 битов, даже если два из этих битов иногда «теряются» при представлении меньших десятичных чисел. Форматы фиксированной длины также часто занимают место, выравнивая размеры полей по общим границам памяти процессора, чтобы повысить скорость обработки. Поле, которое должно принимать значения от 0 до 3, даже если для представления полного набора значений требуется только два бита, может быть закодировано как 8-битовое поле (полный октет), чтобы обеспечить всегда выравнивание следующего поля на границе октета для более быстрой обработки в памяти. Гибкость - то, где кодирование фиксированной длины часто сталкивается с проблемами. Если какое-либо поле определено как 8-битное значение (один октет) в исходной спецификации, нет очевидного способа изменить длину поля для поддержки новых требований. Основной способ решения этой проблемы в схемах кодирования с фиксированной длиной - через номер версии. Если длина поля должна быть изменена, номер версии изменяется в форматах пакетов, поддерживающих новую длину поля. Это позволяет реализациям использовать старый формат, пока все устройства в сети не будут обновлены для поддержки нового формата; после того как все они обновлены, вся система может быть переключена на новый формат, будь то больше или меньше.
img
В прошлой статье мы рассказывали о ресурсе HIBP, на котором можно, проверить находится ли ваш email или пароль в базе взломанных учётных данных. В этой статье расскажем о расширении от Google, которое может выполнять такую же проверку автоматически на любом сайте, где вы вводите учётные данные, используя браузер Google Chrome. Расширение, описанное в данной статье, актуально только для пользователей браузера Google Chrome. Остальным же, мы надеемся, будет просто полезно ознакомиться с возможностями решения. Похоже, что факт обнаружения баз слитых учёток Collection #1 и последующих более крупных Collection #2-5, не остался без внимания Google. Потому что 5 февраля (в день безопасного Интернета, кстати) они объявили о создании сразу двух расширений, которые призваны сделать процесс работы с вэб-ресурсами и приложениями ещё более безопасным. Про одно из них мы бы хотели рассказать в нашей статье. Password Checkup Проверяет учётные данные, которые вы вводите на каждом сайте или в приложении через Google, по базе из свыше 4 миллиардов взломанных логинов и паролей. Если расширение обнаруживает ваши логин и пароль (то есть оба типа данных, которые необходимы для получения доступа к вашему аккаунту) в списке взломанных, то оно генерирует оповещение с предложением сменить скомпрометированные данные. При этом, расширение не будет уведомлять о том, что вы используете слабый пароль или о том, что ваш старый, не актуальный пароль был скомпрометирован. Google заявляет, что разрабатывал расширение так, чтобы учетные данные, которые вы вводите, никогда не попали не только в злоумышленникам, но и в сам Google, в этом им помогали эксперты в области криптографии Стэндфордского Университа. Итак, как это работает? Когда вы вводите на каком-либо сайте свой логин и пароль расширение обращается к серверам Google для того, чтобы проверить находятся ли введённые учётные данные в списке скомпрометированных. При этом, в запросе не передаются сами логин и пароль. То есть расширение опрашивает сервер, не передавая туда запрашиваемую информацию. При этом, важно исключить возможность использования расширения злоумышленниками, которые будут брутить сайты и пробовать получить от расширения информацию о скомпрометированных учётках. Для этого в расширении применяется сразу несколько технологий шифрования, многоразовое хэширование вводимой информации, а также технологии Private Set Intersection (PSI) и k-annonimity. Google имеет в своём распоряжении базу из взломанных учётных данных, содержащих около 4 миллиардов записей. Однако, это не учётные данные в открытом виде, а их захэшированная и зашифрованная копия, ключ от которой известен только Google. Каждый раз, когда вы вводите свой логин и пароль, расширение Password Checkup будет отправлять на сервера Google захэшированную копию этих данных, ключ от которых будет известен только вам. В свою очередь на сервере Google эта копия также будет зашифрована специальным ключом. Последнее преобразование происходит локально в самом расширении - полученная копия от Google дешифруется и если результат сходится с тем хэшом скомпрометированных учётных данных, что хранится на сервере Google - то пользователю выводится Алерт с рекомендациями по смене пароля. Если вы пользуетесь браузером Google Chrome, то рекомендуем установить данное расширение, чтобы обезопасить свои аккаунты от доступа к ним третьих лиц. И никогда, пожалуйста, не используйте одни и те же пароли на разных сайтах.
img
Что такое парадигмы программирования? Это не более, чем просто замысловатое название для популярных способов и стилей организации процесса написания программного кода. Я постараюсь разбить эту тему на части и дать простое пояснение по каждой парадигме. Таким образом, вы сможете легко понять, о чем говорят люди, когда произносят такие слова, как «объектно-ориентированный», «функциональный» или «декларативный». Давайте начнем! Что такое парадигма программирования? Парадигмы программирования – это различные способы и стили, которые используются для организации программы или языка программирования. Каждая парадигма состоит из определенных структур, функций и взглядов на то, как следует решать известные задачи программирования. Вопрос о том, почему существует так много различных парадигм программирования, схож с вопросом о том, почему существует так много языков программирования. Определенные парадигмы лучше подходят для определенных типов задач. Именно поэтому имеет смысл использовать разные парадигмы для разных типов проектов. Кроме того, методики, которые составляют каждую парадигму, развивались с течением времени. Благодаря достижениям как в области программного, так и аппаратного обеспечения появились различные подходы к решению задач, которых раньше просто не было. И последняя причина – я думаю, это просто творческое начало в человеке. По своей натуре, нам просто нравится создавать новые вещи, улучшать то, что другие когда-то создали, и адаптировать инструменты под себя и свои предпочтения или просто делать их более эффективными (в нашем понимании). Все это привело к тому, что на сегодняшний день мы имеем огромное количество вариантов, которые могут помочь нам написать и структурировать ту или иную программу. Чем парадигма программирования не является? Парадигмы программирования – это не языки и не инструменты. Вы не сможете ничего «создать» с помощью парадигмы. Они больше похожи на некий набор образцов и руководящих принципов, о которых условились большое количество людей, которым они следовали и которые они подробно изложили. Язык программирования не всегда привязан к определенной парадигме. Есть языки, которые были созданы с учетом определенной парадигмы и имеют функции, которые облегчают программирование в этом контексте больше, чем другие (хороший пример – Haskel и функциональное программирование). Однако существуют и «многопарадигмальные» языки. Это означает, что вы можете адаптировать свой код, чтобы он подходил под какую-то из парадигм (хороший пример – JavaScript и Python). При этом парадигмы программирования не являются взаимоисключающими в том смысле, что вы можете без каких-либо проблем использовать приемы из различных парадигм одновременно. Популярные парадигмы программирования Теперь, когда вы знаете, что такое парадигмы программирования, а что к ним не относится, давайте рассмотрим самые популярные из них, их характеристики и сравним их. Имейте в виду, что этот список не полный. Существуют и другие парадигмы программирования, которые мы здесь рассматривать не будем. Здесь я расскажу вам только о самых популярных и широко используемых. Императивное программирование Императивное программирование – это набор подробных инструкций, которые даются компьютеру, чтобы тот выполнил их в заданном порядке. Этот тип программирования называется «императивным», потому что мы некоторым образом указываем компьютеру (как программисты), что он должен делать. Императивное программирование концентрируется на описании того, как программа работает, шаг за шагом. Допустим, вы хотите испечь торт. Ваша императивная программа для такого рода задачи может выглядеть следующим образом: 1- Pour flour in a bowl 2- Pour a couple eggs in the same bowl 3- Pour some milk in the same bowl 4- Mix the ingredients 5- Pour the mix in a mold 6- Cook for 35 minutes 7- Let chill Воспользуемся конкретным примером и предположим, что мы хотим отфильтровать массив чисел так, чтобы остались только числа, которые больше 5. Наш императивный код тогда будет выглядеть следующим образом: const nums = [1,4,3,6,7,8,9,2] const result = [] for (let i = 0; i < nums.length; i++) { if (nums[i] > 5) result.push(nums[i]) } console.log(result) // Output: [ 6, 7, 8, 9 ] Обратите внимание, что мы указываем программе, что нужно перебрать каждый элемент массива, сравнить каждый из них с 5 и, если элемент больше 5, то поместить его в конечный массив. Наши инструкции предельно детализированы и конкретны, и именно это и является императивным программированием. Процедурное программирование Процедурное программирование – это производное от императивного программирования только с функциями (также известных как «процедуры» или «подпрограммы»). Процедурное программирования предлагает пользователю разделить выполнение программы на функции, чтобы оптимизировать модульный принцип организации. Вернемся к нашему примеру с тортом. Процедурная программа для этого примера будет выглядеть следующим образом: function pourIngredients() { - Pour flour in a bowl - Pour a couple eggs in the same bowl - Pour some milk in the same bowl } function mixAndTransferToMold() { - Mix the ingredients - Pour the mix in a mold } function cookAndLetChill() { - Cook for 35 minutes - Let chill } pourIngredients() mixAndTransferToMold() cookAndLetChill() Как вы можете видеть, благодаря реализации функций, мы можем просто прочитать три вызова функций в конце файла и понять, что делает наша программа. Такое упрощение и абстрактное представление является одним из преимуществ процедурного программирования. Однако внутри функций находится все тот же императивный код. Функциональное программирование Функциональное программирование продвигает концепцию создания функций немного дальше. В функциональном программировании функции рассматриваются как «полноправные граждане». Это означает, что их можно присваивать переменным, передавать в качестве аргумента и возвращать в качестве результата других функций. Еще одна ключевая концепция – это идея чистых функций. Чистая функций – это функция, которая, чтобы получить результат, полагается только на свои входные данные. И при одних и тех же входных данных всегда будет один и тот же результат. Кроме того, эти функции не имеют никаких побочных эффектов (то есть не вносят никаких изменений вне контекста функции). С учетом всех этих концепций, функциональное программирование призывает писать программы с помощью функций. Оно также поддерживает идею о том, что модульность кода и отсутствие побочных эффектов облегчают определение и разделение обязанностей внутри кодовой базы. Таким образом, это облегчает сопровождение кода. Вернемся к примеру с фильтрацией массива. В императивной парадигме мы можем использовать внешнюю переменную для хранения результата функции, что по сути может считаться побочным эффектом. const nums = [1,4,3,6,7,8,9,2] const result = [] // External variable for (let i = 0; i < nums.length; i++) { if (nums[i] > 5) result.push(nums[i]) } console.log(result) // Output: [ 6, 7, 8, 9 ] Для того, чтобы преобразовать это в функциональное программирование, мы можем сделать следующее: const nums = [1,4,3,6,7,8,9,2] function filterNums() { const result = [] // Internal variable for (let i = 0; i < nums.length; i++) { if (nums[i] > 5) result.push(nums[i]) } return result } console.log(filterNums()) // Output: [ 6, 7, 8, 9 ] Это практически тот же самый код, но мы проворачиваем все итерации внутри функции, в которой мы также сохраняем и массив результатов. Таким образом, мы можем гарантировать, что функция не будет ничего менять за своими пределами. Она создает переменную только для обработки своей собственной информации, и после завершения своей работы удаляет ее. Декларативное программирование Декларативное программирование скрывает всю сложность и приближает языки программирования к человеческому языку и мышлению. Это абсолютная противоположность императивному программированию, хотя бы потому что программист дает инструкции не о том, как компьютеру следует решать задачу, а о том, какой требуется результат. Будет намного понятнее, если мы приведем пример. Воспользуемся примером с фильтрацией массива. Декларативный подход здесь будет выглядеть следующим образом: const nums = [1,4,3,6,7,8,9,2] console.log(nums.filter(num => num > 5)) // Output: [ 6, 7, 8, 9 ] Обратите внимание, что, используя функцию фильтрации filter, мы явно не указываем компьютеру перебирать массив или сохранять значения в отдельном массиве. Мы просто говорим о том, что мы хотим («filter») и условие, которое необходимо выполнить («num > 5»). Что хорошего в таком подходе? Его легче читать и понимать, и зачастую он более емкий в записи. Хорошими примерами декларативного кода являются функции filter, map, reduce и sort в JavaScript. Еще один хороший пример – современные фреймворки/библиотеки JS, такие как React. Посмотрите, например, на этот код: <button onClick={() => console.log('You clicked me!')}>Click me</button> Здесь у нас есть кнопка (button) с приемником событий, который запускает функцию console.log при нажатии кнопки. Синтаксис JSX (то, что использует React) совмещает HTML и JS. Это упрощает и ускоряет написание приложений. Но это не то, что браузеры читают и выполняют. Код React позже преобразуются в обычный HTML и JS, а вот это уже то, с чем работают браузеры. JSX является декларативным, поскольку его цель заключается в том, чтобы предоставить разработчикам более удобный и эффективный интерфейс для работы. Здесь также важно отметить, что в декларативном программировании компьютер все равно обрабатывает информацию как императивный код. Если снова вернуться к примеру с массивом, то компьютер по-прежнему выполняет итерацию по массиву, как в цикле for, но нам, как программистам, не нужно писать это напрямую. Декларативное программирование скрывает всю сложность от программиста. Объектно-ориентированное программирование Одной из самых популярных парадигм программирование является объектно-ориентированное программирование (ООП). Основная концепция ООП заключается в разделении понятий на сущности, которые описываются как некие объекты. Каждая сущность группирует заданный набор информации (свойств) и действий (методов), которые может выполнять эта сущность. ООП широко использует классы. Классы - это способ создания новых объектов с помощью макета или шаблона, который задает программист. Объекты, которые были созданы с помощью класса, называются экземплярами. Вернемся к примеру с приготовлением пищи на псевдокоде. Предположим, что в нашей пекарне у нас есть главный повар (по имени Фрэнк) и помощник повара (по имени Энтони). У каждого их них есть определенные обязанности. Если бы мы использовали ООП, то наша программа бы выглядеть следующим образом: // Create the two classes corresponding to each entity class Cook { constructor constructor (name) { this.name = name } mixAndBake() { - Mix the ingredients - Pour the mix in a mold - Cook for 35 minutes } } class AssistantCook { constructor (name) { this.name = name } pourIngredients() { - Pour flour in a bowl - Pour a couple eggs in the same bowl - Pour some milk in the same bowl } chillTheCake() { - Let chill } } // Instantiate an object from each class const Frank = new Cook('Frank') const Anthony = new AssistantCook('Anthony') // Call the corresponding methods from each instance Anthony.pourIngredients() Frank.mixAndBake() Anthony.chillTheCake() Преимущество ООП заключается в том, что оно облегчает понимание программы за счет четкого разделения задач и обязанностей. Итоги Как мы увидели, парадигмы программирования – это различные способы решения задач программирования и организации нашего кода. Одними из самых популярных и широко используемых на сегодняшний день парадигм являются императивная, процедурная, функциональная, декларативная и объектно-ориентированная. Знание о том, что они из себя представляют, полезно для общего развития, а также для лучшего понимания других тем, связанных с программированием.
ВЕСЕННИЕ СКИДКИ
40%
50%
60%
До конца акции: 30 дней 24 : 59 : 59