منشور بالعلم الأبيض ، أو كيف حفظت دورة الفيديو الخاصة بك من الظهور على المتعقب

captain_barbossa.jpg

مرحبا يا هبر! حسنًا ، أشعر أننا التقينا بالفعل ... آه ، نعم. فيما يلي المنشور الذي ناقشنا فيه بشكل عجيب ما إذا كان من المقبول مراقبة البيئة ، وقصر المستخدم على عدد الأجهزة للعرض ، وتوفير الملفات القابلة للتنفيذ بدلاً من مقاطع الفيديو المدفوعة ، والتصرف بشكل مختلف بكل طريقة ممكنة عند تنظيم "حماية" دورات الفيديو من القرصنة.

وكل شيء سيكون على ما يرام ، لكن من المستحيل الانتقاد دون اقتراح حل في المقابل. "هل يمكنك أن تفعل أفضل؟" - صرخت من التعليقات. "سيكون من الأفضل دعم مواطن ، والمساعدة في جعل منتجهم أفضل!" - أروي بعض الأفكار العامة لفترة وجيزة. المعرض. لذلك ، أنا حقا يمكن أن تفعل أفضل . على الأقل ، لن يتطلب اقتراحي من المستخدم النهائي تشغيل برامج ملتوية بدلاً من ملفات الفيديو المتوقعة.

حل لجميع المشاكل


والحل هو أكثر الأصدقاء تافها: العلامات المائية. نعم ، فقط علامات مائية. بدلاً من الخروج بآليات معقدة للربط بجهاز معين ، "وقع" على تسلسل الفيديو. هذا كل شيء.

ما هي الخصائص التي يجب أن تمتلكها العلامة المائية من أجل أداء وظيفة دفاعية:

  1. يجب أن تحتوي العلامة المائية على معلومات تحدد هوية المستخدم الذي قام بشراء دورة الفيديو بشكل فريد. يمكن أن يكون هذا مفتاح تنشيط يتم إصداره للمستخدم ، أو تسجيل دخول المستخدم تم الحصول عليه عند التسجيل على موقع الويب الخاص بشراء دورة تدريبية عبر الفيديو ، أو طوابع زمنية تتوافق مع وقت شراء الدورة التدريبية (بالطبع ، إذا كان يمكنك ربطهم بشكل لا لبس فيه بهوية المشتري) ، أو أي شيء من هذه الأوبرا.
  2. يجب أن تغطي العلامة المائية معظم الإطار بحيث لا يمكن قطعه دون خسائر كبيرة في الدورة التدريبية للفيديو.
  3. يجب أن يكون مخطط تراكب العلامة المائية عشوائيًا لكل نسخة من الدورة التدريبية حتى لا يكتب الشرير جهازًا آليًا لاستبعاد العلامة المائية نفسها.

إذا جعلت العلامة المائية شفافة للغاية ، فلن يتداخل وجودها مع المستخدم ، ولكن لا يزال من الجدير ذكر ذلك في وصف الدورة التدريبية قبل السداد .

وبالتالي ، من أجل استخراج معلومات كاشفة ، يحتاج القراصنة المحتملون إلى اتباع أحد السيناريوهات الموضحة أدناه:

  1. قم بقطع العلامة المائية بالكامل (تذكر أنه وفقًا للخاصية الثانية ، يجب أن تحتل العلامة المائية كامل الشاشة وتستمر في أداء وظائفها الواقية حتى إذا تم محوها جزئيًا) ، وبالتالي إبطال مقطع الفيديو (في رأيي ، من المنطقي أنه في حالة عدم وجود معظم الفيديو ، لا يوجد أي قيمة للفيديو).
  2. قم بتحرير كل إطار على حدة للتخلص من العلامة المائية دون التسبب في أضرار كبيرة للفيديو. يزيد تعقيد تنفيذ مثل هذا الإجراء يدويًا عن إنشاء مقطع فيديو من البداية ، ووفقًا للخاصية الثالثة ، لا يملك الدخيل القدرة على أتمتة العملية.
  3. (؟) أعتقد أنه يمكنك طلب شبكة عصبية ذكية للقيام بذلك نيابة عنك. وإن لم تكن متأكدا ، وليس متخصصا ، يمكنك تصحيح لي في التعليقات.

دليل على المفهوم


في نصف ساعة ، تمت كتابة نص تافه من 100 سطر ، مما يدل على بساطة وسهولة الوصول إلى تنفيذ هذه الحماية. أؤكد : ليس لإظهار مدى ذكوتي ، بل على العكس تمامًا ، أن أشير إلى أن الشخص بعيد جدًا عن معالجة الصور كان قادرًا على تكوين رمز يعمل بالكامل (في إطار المفسد) في نصف ساعة ، وبهذه البساطة:

fckInfoprotectorV2.py
#!/usr/bin/env python3 # -*- coding: utf-8 -*- # Usage: python3 fckInfoprotectorV2.py import os from shutil import rmtree import numpy as np import cv2 class VideoSigner: def __init__(self, video, watermark): os.makedirs('original') os.makedirs('watermarked') self.vidin = cv2.VideoCapture(video) self.fps = self.vidin.get(cv2.CAP_PROP_FPS) self.frame_size = ( int(self.vidin.get(cv2.CAP_PROP_FRAME_WIDTH)), int(self.vidin.get(cv2.CAP_PROP_FRAME_HEIGHT)) ) self.watermark = cv2.imread(watermark, cv2.IMREAD_UNCHANGED) self.wH, self.wW = self.watermark.shape[:2] B, G, R, A = cv2.split(self.watermark) B = cv2.bitwise_and(B, B, mask=A) G = cv2.bitwise_and(G, G, mask=A) R = cv2.bitwise_and(R, R, mask=A) self.watermark = cv2.merge([B, G, R, A]) def __del__(self): rmtree('original') rmtree('watermarked') def _split(self): print('[*] Splitting video by frames... ', end='', flush=True) (success, image), count = self.vidin.read(), 0 while success: path = os.path.join('original', f'{count}.jpg') cv2.imwrite(path, image) success, image = self.vidin.read() count += 1 print('Done') def _watermark(self): print('[*] Signing each frame... ', end='', flush=True) for image_name in sorted( os.listdir('original'), key=lambda x: int(x.split('.')[0]) ): image_path = os.path.join('original', image_name) image = cv2.imread(image_path) h, w = image.shape[:2] image = np.dstack([ image, np.ones((h, w), dtype='uint8') * 255 ]) overlay = np.zeros((h, w, 4), dtype='uint8') half_h_diff = (h - self.wH) // 2 half_w_diff = (w - self.wW) // 2 overlay[half_h_diff:half_h_diff + self.wH, half_w_diff:half_w_diff + self.wW] = self.watermark output = image.copy() cv2.addWeighted(overlay, 0.25, output, 1.0, 0, output) path = os.path.join('watermarked', image_name) cv2.imwrite(path, output) print('Done') def _merge(self): print('[*] Merging signed frames... ', end='', flush=True) self.vidout = cv2.VideoWriter( 'signed.avi', cv2.VideoWriter_fourcc(*'XVID'), fps=self.fps, frameSize=self.frame_size ) for image_name in sorted( os.listdir('watermarked'), key=lambda x: int(x.split('.')[0]) ): image_path = os.path.join('watermarked', image_name) image = cv2.imread(image_path) self.vidout.write(image) print('Done') def sign(self): self._split() self._watermark() self._merge() if __name__ == '__main__': signer = VideoSigner('SampleVideo_1280x720_1mb.mp4', 'watermark.png') signer.sign() 


نتيجة البرنامج النصي ، في هذا المثال كمثال:

sample_original.gif

sample_signed.gif


ليس من أجل الضجيج ، ولكن فقط من أجل الصالح العام.

لدي الشرف.

Source: https://habr.com/ru/post/ar450344/


All Articles