Привет друг, меня зовут Артем / Brendan8c
Я инженер-программист, специализирующийся на создании веб-проектов.
Меня вдохновляет возможность делиться интересными идеями через веб-разработку.
Готов помочь вам с созданием веб-сайта на WordPress, разработкой одностраничного сайта или написанием Python-кода для оптимизации вашей работы.
Давайте обсудим вашу идею и воплотим её в жизнь!
Technology stack:
Воспроизведение звука при клике.
Несколько дней я тестировал контекстную рекламу Яндекс на своём сайте.
Как это обычно бывает, я сначала запилю весь функционал, чтоб всё работало, а потом начинаю глубже разбираться в данном вопросе.
Так и в этот раз оказалось, что доход с 1000 показов такого блока составит около 150 рублей. Я это даже за деньги не считаю.
Да и данный веб сайт не является тем сайтом на котором высокий трафик просмотров в отличие от того же онлайн кинотеатра.
Онлайн кинотеатр является полностью бесплатным проектом для всех пользователей и вставлять рекламу там я не собираюсь. Хостеры которые предоставляют все фильмы и сериалы уже встроили свою рекламу в плееры и это не моих рук дело…
На данном сайте находится мой личный блог по разработке и обычным пользователям он не интересен, по этому посещаемость в разы ниже.
Было принято решение по удалению Яндекс рекламы.
При клике на подобный блок я привязал скрипт который, воспроизводил звук и теперь когда нет рекламы то, и скрипт можно вырезать.
Вот собственно он:
// Воспроизводим звук при клике на постер Yandex рекламы ;)
const audio = new Audio('https://youowl.ru/#####/zvuk.mp3');
const element = document.getElementById('yandex_rtb_R-A-3561837-1');
let isPlaying = false;
element.addEventListener('click', () => {
if (isPlaying) {
return;
}
audio.play();
isPlaying = true;
// Обработчик события окончания воспроизведения аудио
audio.onended = () => {
isPlaying = false;
};
});
AES (Advanced Encryption Standard) с ключом 256 бит.
Это один из самых надежных методов шифрования файлов, используемых в современных компьютерных системах. Он обеспечивает высокий уровень безопасности, защищая данные от несанкционированного доступа и атак. Шифрование с использованием AES 256 предоставляет надежную защиту конфиденциальности данных, делая их практически непроницаемыми для злоумышленников.
Процесс шифрования с использованием AES 256 включает в себя несколько шагов:
- Выбор ключа: Ключ шифрования состоит из 256 бит (32 байта) и используется для преобразования исходных данных в зашифрованный формат и обратно.
- Инициализация раундов: Алгоритм AES состоит из нескольких раундов (обычно 10 для 256-битного ключа), в каждом из которых происходят определенные операции с данными.
- Замешивание данных (SubBytes): Каждый байт данных заменяется на соответствующий байт из заранее определенной таблицы (S-Box). Это обеспечивает нелинейность и запутывание данных.
- Перемешивание столбцов (ShiftRows): Байты в каждой строке матрицы состояния сдвигаются на фиксированное количество позиций влево. Это дополнительно усложняет структуру данных.
- Комбинирование столбцов (MixColumns): Байты в каждом столбце матрицы состояния преобразуются с использованием определенных математических операций. Это способствует диффузии данных.
- Добавление раундового ключа (AddRoundKey): Каждый байт данных XOR-ится с соответствующим байтом ключа текущего раунда. Это окончательное изменение данных перед следующим раундом.
- Повторение раундов: Шаги с 3 по 6 повторяются определенное количество раз (10 раз для AES 256) для обеспечения высокой степени безопасности.
- Финальный раунд без MixColumns: В последнем раунде не выполняется операция MixColumns, что делает расшифровку возможной.
Применение AES 256 обеспечивает надежную защиту файлов и данных от множества угроз, включая перехват, вмешательство и взлом.
Для представления масштаба времени.
AES 256 — крайне надежный метод шифрования. Взлом его практически невозможен из-за огромного числа возможных ключей (приближенно 1.1579209×10771.1579209×1077). Современные компьютеры не могут справиться с таким объемом вычислений.
Если представить, что злоумышленники имеют доступ к мощному вычислительному оборудованию, которое способно проверять 1 миллиард (10^9) ключей в секунду, то время, необходимое для проверки всех возможных комбинаций ключей, составит: 10^9 ключей/сек ≈ 3.6710587×10^67 секунд.
Для сравнения, возраст вселенной оценивается примерно в 4.32×10174.32×1017 секунд. Таким образом, время «великой вероятности» для взлома файла, зашифрованного алгоритмом AES 256, выходит за пределы времени существования нашей Вселенной.
Файл Encryption_AES_256.py для зашифровывания.
import os
from Crypto.Cipher import AES
from Crypto.Random import get_random_bytes
# Список файлов, которые нужно игнорировать
IGNORED_FILES = ["Decryption_AES_256.py", "Decryption_AES_256_One_file.py",
"Encryption_AES_256.py", "Encryption_AES_256_One_file.py",
"256_KeyGen.py"]
def encrypt_file(input_file, output_file, key):
# Генерируем случайный вектор инициализации (IV) длиной, соответствующей размеру блока AES (16 байт)
iv = get_random_bytes(16)
# Создаем объект AES с ключом и режимом шифрования CBC
cipher = AES.new(key, AES.MODE_CBC, iv)
# Читаем содержимое файла
with open(input_file, 'rb') as file_in:
data = file_in.read()
# Если данные не кратны 16 байтам, дополняем их
if len(data) % 16 != 0:
data += b' ' * (16 - len(data) % 16)
# Шифруем данные
encrypted_data = cipher.encrypt(data)
# Записываем IV и зашифрованные данные в выходной файл
with open(output_file, 'wb') as file_out:
file_out.write(iv + encrypted_data)
def encrypt_directory(directory, key):
for root, _, files in os.walk(directory):
for filename in files:
input_file = os.path.join(root, filename)
output_file = input_file
if filename not in IGNORED_FILES:
encrypt_file(input_file, output_file, key)
# print(f"Файл '{input_file}' успешно зашифрован.")
if __name__ == '__main__':
# Путь к папке, которую нужно зашифровать
directory = r'E:\My files\Dev\Encryption_AES_256'
# 256-битный ключ (32 байта)
key_hex = "00112233445566778899AABBCCDDEEFF00112233445566778899AABBCCDDEEFF"
key = bytes.fromhex(key_hex)
encrypt_directory(directory, key)
print(f"Encryption completed for on folder '{directory}'.")
# Зашифровывает
# pip install pycryptodome
# Для запуска: python Encryption_AES_256.py
Файл Decryption_AES_256.py для дешифрации.
from Crypto.Cipher import AES
import os
import shutil
def decrypt_file(input_file, output_file, key):
chunk_size = 64 * 1024 # 64 KB
# Читаем вектор инициализации (IV) из начала входного файла
with open(input_file, 'rb') as file_in:
iv = file_in.read(16)
# Создаем объект AES с ключом и режимом шифрования CBC
cipher = AES.new(key, AES.MODE_CBC, iv)
# Открываем файлы для чтения и записи
with open(input_file, 'rb') as file_in:
with open(output_file, 'wb') as file_out:
# Пропускаем первые 16 байт (IV)
file_in.read(16)
while True:
chunk = file_in.read(chunk_size)
if len(chunk) == 0:
break
try:
# Расшифровываем блок данных и записываем в выходной файл
decrypted_chunk = cipher.decrypt(chunk)
file_out.write(decrypted_chunk)
except ValueError as e:
# Если возникла ошибка, оставляем исходный файл без изменений
print(f"Ошибка при расшифровке файла '{input_file}': {e}")
shutil.copyfile(input_file, output_file)
break
# Удаляем дополнение, если присутствует
file_out.truncate()
def is_ignored_file(file_path):
# Список файлов, которые нужно игнорировать
ignored_files = [
"Decryption_AES_256.py",
"Decryption_AES_256_One_file.py",
"Encryption_AES_256.py",
"Encryption_AES_256_One_file.py",
"256_KeyGen.py"
]
# Игнорируем файлы по имени
file_name = os.path.basename(file_path)
return file_name in ignored_files
def decrypt_directory(directory_path, key):
for root, _, files in os.walk(directory_path):
for file_name in files:
input_file = os.path.join(root, file_name)
output_file = os.path.join(root, f"decrypted_{file_name}")
if not is_ignored_file(input_file):
decrypt_file(input_file, output_file, key)
os.remove(input_file)
# Перемещаем обратно в исходное место
shutil.move(output_file, input_file)
if __name__ == '__main__':
# Путь к папке для дешифрации файлов
directory_path = r"E:\My files\Dev\Encryption_AES_256"
# 256-битный ключ (32 байта)
key_str = "00112233445566778899AABBCCDDEEFF00112233445566778899AABBCCDDEEFF"
key = bytes.fromhex(key_str)
decrypt_directory(directory_path, key)
print("Все файлы в папке успешно расшифрованы.")
# Расшифровывает
# pip install pycryptodome
# Для запуска: python Decryption_AES_256.py
Файл 256_KeyGen.py для генерации ключей.
import os
import secrets
def generate_256_bit_key():
# Генерируем случайные байты длиной 32 (256 бит)
key = secrets.token_bytes(32)
return key
if __name__ == '__main__':
key = generate_256_bit_key()
print("Сгенерированный 256-битный ключ:")
print(key.hex().upper())
# Скрипт сгенерирует 256 битный ключ
# Для запуска: python 256_KeyGen.py
# Этот скрипт использует secrets.token_bytes() для генерации криптографически безопасных случайных байтов, и затем преобразует байты в строку шестнадцатеричного представления (hex) для вывода в консоль. Вы получите ключ длиной 32 байта, что соответствует 256 битам.
clean-css — это быстрый и эффективный CSS-оптимизатор для платформы Node.js и любого современного браузера.
Написал готовую часть кода, чтобы была возможность использовать данный плагин напрямую в Gulp, без использования сторонних плагинов.
Есть плагины которые адаптируют данный плагин таким образом, что-бы он работал в Gulp сборках, но проблема в том, что пользователям приходится ждать когда они обновят его до новой версии. Данный код решает эту проблему.
const { src, dest, series } = require('gulp');
const CleanCSS = require('clean-css');
const concat = require('gulp-concat');
function css() {
const options = {
compatibility: '*', // (default) - Internet Explorer 10+ compatibility mode
inline: ['all'], // enables all inlining, same as ['local', 'remote']
level: 2 // Optimization levels. The level option can be either 0, 1 (default), or 2, e.g.
// Please note that level 1 optimization options are generally safe while level 2 optimizations should be safe for most users.
};
return src('app/**/*.css')
.pipe(concat('style.min.css'))
.on('data', function(file) {
const buferFile = new CleanCSS(options).minify(file.contents)
return file.contents = Buffer.from(buferFile.styles)
})
.pipe(dest('build'))
}
exports.css = series(css)
Репозиторий плагина Clean-css
Набор инструментов для обработки и сжатия JavaScript для ES6+.
Написал готовую часть кода, чтобы была возможность использовать данный плагин напрямую в Gulp, без использования сторонних плагинов.
Есть плагины которые адаптируют данный плагин таким образом, что-бы он работал в Gulp сборках, но проблема в том, что пользователям приходится ждать когда они обновят его до новой версии. Данный код решает эту проблему.
const { src, dest, series } = require('gulp');
const { minify } = require('terser');
function js() {
const options = {
parse: {
bare_returns: true, // (default false) -- support top level return statements.
html5_comments: true, // (default true)
shebang: true // (default true) -- support #!command as the first line.
}
};
return src('app/**/*.js')
.on('data', function(file) {
async function getJs() {
const result = await minify(file.contents.toString(), options);
return await minify(result)
}
(async function() {
try {
file.contents = Buffer.from(JSON.parse(Buffer.from(JSON.stringify(await getJs()))).code)
} catch (error) {
const { message, line, col, pos } = error
console.log('message: ' + message)
console.log('filename: ' + file.basename)
console.log('line: ' + line)
console.log('col: ' + col)
console.log('pos: ' + pos)
}
})();
})
.pipe(dest('build'))
}
exports.js = series(js)
Репозиторий плагина Terser
HTML-компрессор/минификатор на базе Javascript.
Написал готовую часть кода, чтобы была возможность использовать данный плагин напрямую в Gulp, без использования сторонних плагинов.
Есть плагины которые адаптируют данный плагин таким образом, что-бы он работал в Gulp сборках, но проблема в том, что пользователям приходится ждать когда они обновят его до новой версии. Данный код решает эту проблему.
const { src, dest, series } = require('gulp');
const htmlMinify = require('html-minifier');
const options = {
includeAutoGeneratedTags: true,
removeAttributeQuotes: true,
removeComments: true,
removeRedundantAttributes: true,
removeScriptTypeAttributes: true,
removeStyleLinkTypeAttributes: true,
sortClassName: true,
useShortDoctype: true,
collapseWhitespace: true
};
function html() {
return src('app/**/*.html')
.on('data', function(file) {
const buferFile = Buffer.from(htmlMinify.minify(file.contents.toString(), options))
return file.contents = buferFile
})
.pipe(dest('build'))
}
exports.html = series(html)
Репозиторий плагина html-minifier
Генератор визуальной структуры каталогов и файлов.
Эта программа создает визуальный каталог файловой системы, отображая файлы и папки в виде иерархической древовидной структуры.
Как использовать:
- Просто скопируйте ваш путь к каталогу и вставьте его в приложении DirTreeGenerator.exe
- Обратите внимание изначально в приложении указано игнорировать такие каталоги как: .git, .vscode, node_modules а также будут проигнорированы все файлы и подкаталоги внутри этих папок. У вас есть возможность добавлять или удалять каталоги.
- Вы может включить чекбокс (No files), после этого программа будет учитывать только каталоги, все файлы будут проигнорированы.
- Также вы можете использовать вместо приложения файл fast_DirTreeGenerator.bat. Для того чтобы добавить или удалить каталог, вам нужно будет отредактировать в файле fast_DirTreeGenerator.py значение переменной IGNORED_FOLDERS = [‘.git’, ‘.vscode’, ‘node_modules’].

- Если вы хотите сами собрать проект используйте эти ключи.
Для Linux:pyinstaller --onefile --windowed --icon=app.png DirTreeGenerator.py
Для macOS:pyinstaller --onefile --windowed --icon=app.icns DirTreeGenerator.py
Для Windows:pyinstaller --onefile --windowed --icon=app.ico DirTreeGenerator.py
- Установите необходимые зависимости:
pip install pyinstaller
,pip install pyqt5
- Для того чтобы добавить свой шрифт, вам нужно преобразовать его в формат base64, для этого в файле Code_base64.py отредактируйте эту строку
font_file = "TiltNeon-Regular.ttf"
изменив значение переменной на название вашего шрифта., Запустите данный файл, после чего он создаст текстовый файл Font_base64.txt который будет содержать нужную вам кодировку., Затем в файле DirTreeGenerator.py измените значение переменнойbase64_font = 'your_base64_here'
на ваши символы base64. - Чтобы изменить иконку файла для панели задач в Windows вам так-же нужно преобразовать её в формат base64, указав в файле Code_base64.py за место
font_file = "TiltNeon-Regular.ttf"
ваш файл с иконкой. После чего вы сможете изменить её в переменнойbase64_icon = 'your_base64_here'
.

Файл 35mb, зависимости должны быть установлены!
Файл 218mb, работает без установки зависимостей
Файл .bat работает совместно с файлом fast_DirTreeGenerator.py, зависимости должны быть установлены!
Поиск фильмов и сериалов по ID КиноПоиск.
Это сайт-агрегатор открытых и закрытых видео-хостингов на наличие фильмов и сериалов.
Он позволяет находить фильмы и сериалы по kinopoisk id.
• Всё что тебе нужно это зайти на сайт kinopoisk
• Скопировать из браузерной строки ID фильма или сериала
• Перейти на сайт https://owlov.ru и вставить этот ID в поле для поиска.

Техническая часть.
Данный сайт работает совместно с моим отдельным сервером, отправляя запросы и получая ответ. Сделано это было для того, чтобы скрыть личные токены которые были предоставлены видеохостингами. Располагается на GitHub Pages и использует SSL сертификат от CloudFlare.

My works
В этом разделе собраны некоторые из моих проектов с описанием.