تشفير التسريع: ندرس مقياس التسارع لجهاز Android باستخدام مهمة NeoQUEST-2019



يعد مقياس التسارع - المعروف أيضًا باسم G-sensor - أحد أكثر أجهزة الاستشعار شيوعًا اليوم. يمكنك مقابلته في كل أداة حديثة تقريبًا. يؤدي مقياس التسارع مهمة بسيطة إلى حد ما - فهو يقيس تسريع الجهاز. دعونا نرى كيف يفعل ذلك - دعنا نحلل آليات أجهزة استشعار API أندرويد باستخدام مثال المهمة رقم 7 من المرحلة الإلكترونية من NeoQUEST-2019.

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

[1749054104147639] [2.07154922] [10.001905] [4.5387093] [1749056073889025] [5.7193284] [8.221763] [0.01391537] [1749058029180773] [4.684068] [12.05614] [0.0377285] [1749060105291613] [4.6900544] [6.9307165] [4.7094293] [1749062123327502 ] [4.4682417] [7.512769] [6.037215] [1749067640096818] [1.0396843] [8.798672] [4.9335976] [1749070016073380] [2.3173676] [10.180047] [[4.948362]] 2.48394698] [10.834006] [6.306282] [1749075827770391] [0.2795044] [13.279829] [0.19391555]

نرى أن النص عبارة عن مجموعة مكررة مكونة من 4 قيم ، واحدة منها عدد صحيح ، والباقي 3 عبارة عن أرقام الفاصلة العائمة. للراحة ، وضعناها في خطوط منفصلة:

[1749054104147639] [- 2.07154922] [10.001905] [4.5387093]
[1749056073889025] [5.7193284] [8.221763] [0.01391537]
[1749058029180773] [- 4.684068] [12.05614] [0.0377285]
[1749060105291613] [4.6900544] [6.9307165] [- 4.7094293]
[1749062123327502] [4.4682417] [7.512769] [6.037215]
[1749067640096818] [1.0396843] [8.798672] [- 4.9335976]
[1749070016073380] [- 2.3173676] [10.180047] [4.948362]
[1749072343679582] [- 4.3660607] [12.218135] [0.5312999]
[1749073674459611] [- 2.48394698] [10.834006] [- 6.306282]
[1749075827770391] [0.2795044] [13.279829] [- 0.19391555]

تم فرز تنسيق التشفير ، ولكن ما هي هذه القيم غير معروفة. بعض المعلمات من التسارع للجهاز ، دون أي تفاصيل. ودعنا نذهب إلى موقع مطوري Android ونرى ما يمكن أن يظهره مقياس التسارع بشكل عام.

نرى الوصف التالي:


اكتشفنا ما هي معلمات الفاصلة العائمة المسؤولة عن ذلك - هذا هو تسارع الجهاز على طول المحاور X و Y و Z. لكن كيف نفهم أي محور مسؤول عن كل منها؟ حان الوقت لبدء التطبيق. يبدو مثل هذا:



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

فيما يلي قائمة برموز لتخزين معلومات التسريع:

public class MotionSnapshot { public final float angle_alpha; public final float angle_beta; public final float angle_gamma; public final long event_time; ... } 

بناءً على هذه الاعتبارات ، نواجه المهام التالية:

  1. تحديد القيمة التي في cryptogram يتوافق مع ميل الجهاز
  2. تحديد نمط الانحراف
  3. لكل رقم لربط نمط الانحراف لفك التشفير

سيتم تنفيذ المهام 2 الأولى بالتوازي. على الهاتف يمكننا اختبار نوعين من الميل:

  1. من نفسي / لنفسي
  2. يسار / يمين


الكود المسؤول عن التعامل مع الأحداث من التسارع
 public class SensorListener implements SensorEventListener { private MotionTrace Trace; public SensorListener(MotionTrace trace, MainActivity activity) { Trace = trace; } @Override public void onAccuracyChanged(Sensor sensor, int accuracy) { } @Override public void onSensorChanged(SensorEvent event) { Trace.addSnaphot(new MotionSnapshot(event.values, event.timestamp)); } } 


الكود المسؤول عن توليد ميل الجهاز بنقرة زر واحدة
 public class MotionTrace { private ArrayList<MotionSnapshot> Deltas; private long Length; private MotionSnapshot LastSnapshot; public MotionTrace(long len) { LastSnapshot = new MotionSnapshot(0,0,0,0); Deltas = new ArrayList<>(); Length = len; } public void addSnaphot(MotionSnapshot snapshot) { if (Deltas.size() >= Length) { Deltas.remove(0); } MotionSnapshot delta = new MotionSnapshot(0,0,0,0); if (Deltas.size() > 0) { delta = snapshot; } Deltas.add(delta); } public ArrayList<MotionSnapshot> getDeltas() { return new ArrayList<>(Deltas); } } 


الكود المسؤول عن توليد التشفير
 public void SaveCiphertext() { Log.d(Config.MAIN_TAG, "SAVING - {{" + Ciphertext + "}}"); try { File root = new File(Environment.getExternalStorageDirectory(), Config.DIRNAME); if (!root.exists()) { Log.d(Config.MAIN_TAG, "Creating directory - [" + root + "]"); if (!root.mkdirs()) { Log.d(Config.MAIN_TAG, "Error creating directory"); } } File out_file = new File(root, Config.FILENAME); Log.d(Config.MAIN_TAG, "Out - [" + out_file + "]"); PrintWriter writer = new PrintWriter(out_file, "UTF-8"); writer.println(Ciphertext); writer.close(); Toast.makeText(this, "Saved to - [" + out_file + "]", Toast.LENGTH_LONG).show(); } catch (IOException ex) { Toast.makeText(this, "Error saving data", Toast.LENGTH_SHORT).show(); } Ciphertext = ""; } 


لنبدأ بالترتيب. لاختبار منحدرات النوع الأول ، نختار الرقمين 2 و 8. انقر على كل 3 مرات بجهد متزايد. نحصل على النتيجة التالية:

[2687418463227102] [- 0.23700714] [10.764615] [- 0.9759079]
[2687419411042043] [- 3.5834892] [13.591138] [- 1.7036858]
[2687420383026907] [- 5.575793] [13.533228] [- 1.3104248]
[2687421461360546] [0.6850295] [6.0002656] [0.5568123]
[2687422317256542] [4.1720495] [1.8675026] [1.545407]
[2687423250514599] [7.9689393] [- 3.600097] [0.33846742]

حسنا ، الاختلافات في المعلمة 2 مرئية للعين المجردة. لنبدأ ملء القالب.
نحن نمثل القالب في شكل نطاقات لقيم الحقول المقابلة في سطر التشفير. نحتفل بعلامة استفهام ما لا نعرفه بعد.

]
[(<0) - الانحراف عن النفس ؛ (> 0) - رفض ذاتي]
[؟]
[؟]

وبالمثل ، سنجري اختبارات باستخدام الزرين 4 و 6. النتائج:

[2688019191605386] [1.7270225] [9.541045] [0.0397171]
[2688020247971353] [1.0615791] [9.794326] [4.9135437]
[2688021887957875] [1.0974716] [7.5535636] [7.8307548]
[2688023749896352] [1.3328063] [9.43923] [- 0.27600938]
[2688024849688832] [1.1357567] [9.9313135] [- 2.4410355]
[2688026002520864] [0.30400848] [6.4610033] [- 8.0956335]

قم بتحديث القالب مع مراعاة النمط المدروس:

]
[(<0) - الانحراف عن النفس ؛ (> 0) - رفض ذاتي]
[؟]
[(<0) - الانحراف إلى اليمين ؛ (> 0) - الانحراف إلى اليسار]

من الواضح أن القيمة الثالثة هي الانحراف لأعلى / لأسفل ، لأن هذا هو المتجه الوحيد المتبقي. ونحن لسنا بحاجة بالفعل إلى التحقق من ذلك ، لأنه من أجل التحديد الواضح للزر المضغوط ، لدينا بالفعل القالب المعروف.

سنقوم الآن بإنشاء قالب لكل رقم على لوحة المفاتيح ، استنادًا إلى موضع الأزرار والقالب المطوّر (* - المعلمة لا تهمنا):

1 - [*] [<0] [*] [> 0]
2 - [*] [<0] [*] [قريب من 0]
3 - [*] [<0] [*] [<0]
4 - [*] [] [*] []
5 - [*] [قريب من 0] [*] [قريب من 0]
6 - [*] [على مقربة من 0] [*] [<0]
7 - [*] [> 0] [*] [> 0]
8 - [*] [> 0] [*] [قريب من 0]
9 - [*] [> 0] [*] [<0]
0 - [*] [> 0] [*] [قريب من 0]

كما يتضح من الشكل ، فإن الأزرار 8 و 0 لها نفس المعلمات ، لذلك فك تشفيرها يمكن أن يكون غامضًا - عند تلبية مثل هذا المزيج في cryptogram ، يجب عليك تجربة كلا الخيارين. الآن نطبق القوالب التي تم الحصول عليها على التشفير ، ونحصل على إجابتين: 1029761235 و 1829761235 ، منها 1829761235 صحيحة . اكتمل الواجب!

قريبًا جدًا - في 26 يونيو - ستقام مسابقة NeoQUEST 2019 وجهًا لوجه! عجلوا للتسجيل في موقع الحدث. في المستقبل القريب سيتم الافراج عن habrastatya مع الإعلان عن البرنامج ، لا تفوت!

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


All Articles