กระบวนการเข้ารหัสของ Https ที่ใช้รับส่งข้อมูลระหว่าง Client <-> Server นั้นจะใช้ Cryptography 2 แบบด้วยกัน

https://medium.com/@emilywilliams_43022/cryptography-101-symmetric-encryption-444aac6bb7a3
  1. Symmetric Cryptography (มีกุญแจดอกเดียว) คือใช้กุญแจดอกเดียวในการเข้ารหัส และถอดรหัส โดยกุญแจนี้มักถูกเรียกว่า Secret Key เพราะกุญแจนี้ควรเก็บไว้เป็นความลับ

เนื่องจากได้มีงานเขียน Backend Service (Spring Boot)โดยต้องไปเรียก REST Service Api ของส่วนกลางหลาย ๆ เส้นเพื่อเอา Data มารวมร่างกัน (จนแอปตัวเองแถบจะไม่ต้องใช้ Database เลย @_@) จึงได้รู้จักกับ CompletableFuture ที่จะช่วยให้การทำงาน Async ง่ายขึ้น

Fork-Join framework

Fork-Join framework ถูกเพิ่มเข้ามาใน Java 7 ช่วยเพิ่มความเร็วในการทำงาน โดยแตกงานออกเป็นงานย่อยๆ แล้วให้ทำงานพร้อมกันแบบ Parallel ซึ่งจะกระจายการทำงานไปยัง threads ต่างๆ ใน common thread pool โดยเรียกว่า ForkJoinPool

ForkJoinPool

แต่ละ thread ใน ForkJoinPool จะมี algorithm “workstealing” คือ เมื่อ thread ไหนว่างมันจะไปโขมยงานที่อยู่ในคิวออกมาทำเรื่อย ๆ จนกว่าทุกงานจะเสร็จ

https://www.java-success.com/10-%E2%99%A6-executorservice-vs-forkjoin-future-vs-completablefuture-interview-qa/
https://www.java-success.com/10-%E2%99%A6-executorservice-vs-forkjoin-future-vs-completablefuture-interview-qa/
source: https://www.java-success.com/10-%E2%99%A6-executorservice-vs-forkjoin-future-vs-completablefuture-interview-qa/

CompletableFuture พระเอกของ Asynchronous Task

ถ้าเราไม่ได้ทำการ config ใดๆ เจ้า CompletableFuture จะใช้งาน thread จาก ForkJoinPool ด้านบนนั่นแหละฮะ

  1. CompletableFuture.supplyAsync() เป็นการแตก thread เพื่อแยกไปทำงานจาก main thread ส่วนใหญ่จะใช้ตัวนี้นะ เมื่อทำงานเสร็จแล้วจะ return ผลลัพธ์กลับมาให้เพื่อเอาไปงานต่อ
public CompletableFuture<Double> calculateAsync() { return CompletableFuture.supplyAsync(() -> { try { Thread.sleep(2000); return 5 * 10d; } catch (InterruptedException e) { e.printStackTrace(); } return 0d; }); }…


เมื่อมีผู้ใช้งานโทรศัพท์ Huawei รุ่นใหม่ที่ไม่สามารถใช้งาน Google Service ได้ (โดยเฉพาะลูกค้าคนสำคัญ !!) ดังนั้นเราจึงต้องทำให้แอปให้ Support Huawei Mobile Service จึงได้ไปเจอบทความของ wongnai

จากนั้นเลยทำตามโดยเลือก Solution แบบ Bridge Class เพราะว่ามันน่าจะดีที่สุดโดยเริ่มจาก ใช้ Product Flavor แยกระหว่าง Google กับ Huawei

2. แยก dependencies ตาม Product Flavor เพื่อให้แอปไม่ใหญ่


ใน Android 10 ได้มีการปรับปรุงการใช้งาน และการเข้าถึง Device Storage เพื่อเพิ่มความปลอด และความสะดวกต่อการใช้งาน

  • ปัญหาของการใช้งาน Storage แบบเก่า (Shared Storage)
    1. แต่ละแอปจะมี Private Directory ใน Internal Storage (android/data/com.package.xxx) ซึ่งมันไม่ได้จำกัดการเข้าถึงจากแอปอื่น
    2. แอปส่วนใหญ่จะขอ Permission ที่กว้างมาก เพื่อใช้สำหรับ function ที่ทำงานธรรมดาๆ เช่น โหลดรูป หรือ Image Picker
  • Scoped Storage
  • Scoped Storage จะถูกใช้งานใน Android 10 ขึ้นไป และสำหรับแอป Android ที่ build ด้วย targetSdkVersion: 29 ขึ้นไปแล้วนั้น จะไม่สามารถใช้งาน File API ได้ ( เฉพาะ Device ที่ใช้ Android 10 ขึ้นไป) แต่สามารถ Workaround โดยการ set android:requestLegacyExternalStorage=”true” ใน AndroidManifest.xml. (แต่ไม่แนะนำนะ คือเดี๋ยวยังไงก็ต้องแก้ 5555)
  • Let’s start code ด้วยการ Save File
    เราจะเริ่มด้วย Project ง่ายๆ โดยการ Capture หน้าจอแล้ว Save ลงเครื่องนะครับ

1. สร้าง function getBitmapFromVie() เพื่อใช้ Capture รูปภาพหน้าจอ แล้ว return เป็น Bitmap นะครับ


Application Assessment Overview

Phase 1 — Static analysis
Phase 2 — Dynamic and Runtime analysis
Phase 3— Communication Channel
Phase 4— Server Side and End-to-End Testing

Static analysis

  1. Reverse Engineering on Application Binary

คือการใช้ tools เช่น jadx และ apktool ควบคู่กัน ใช้ในการ Reverse Engineer และเข้าไปแก้ไข Source Code และ compile ใหม่เป็นแอพที่ถูกการแก้ไขจาก hacker
แนวทางป้องกัน -> ใช้การ checksum binary ในแอพพลิเคชั่น

2. Hardcoded Sensitive Information

คือการใส่ FIX ข้อมูลที่สำคัญลงไปใน Source Code เช่น key,username,token
แนวทางป้องกัน -> อย่า FIX ค่าไว้ ถ้าจำเป็นจริงๆ ควรเข้ารหัสข้อมูลด้วย

3. Excessive App Permissions

คือ แอพพลิเคชั่นควรร้องของ Permission เท่าที่ใช้เท่านั้น

4. Unsupported version of OS Installation Allowed

คือ ควรเลือก minSdkVersion ไม่ต่ำจนเกินไป เนื่องจากจะไม่ถูก Support จากผู้พัฒนาทำให้มีความเสี่ยงด้านความปลอดภัย จากรูป แถบสีแดงคือไม่ถูก Support แล้ว

5. Debuggable…


สำหรับงานที่ต้องการกำหนดการใช้งานอุปกรณ์หรืองานประเภทอื่นๆ ที่เราจำเป็นจะ ต้องใช้ Device ID ในการเช็คโดยการดึง Device ID จะประกอบด้วย 5 วิธีหลักดังนี้

1. Unique Telephony Number (IMEI, MEID, ESN, IMSI)

ใช้ได้เฉพาะมือถือหรือ Tablet ที่มีการใส่ซิมการ์ดเท่านั้น emulator หรือ device ที่ไม่มีการใช้งานซิมการ์ดจะไม่สามารถดึงค่าได้

2. MAC Address

เราสามารถดึงค่า mac address ได้จากอุปกรณ์ที่มี wifi หรือ bluetooth hardware แต่วิธีการนี้ไม่แนะนำเพราะว่าทุก device อาจไม่มี wifi hardware และถึงแม้จะมีก็ต้องเปิดใช้งานก่อนถึงจะสามารถดึงค่าได้

3. Serial Number

Device บางรุ่น สามารถกำหนด serial number เองได้ และบาง device อาจไม่มี serial number ก้ได้ ทำให้วิธีการนี้ไม่น่าเชื่อถือ

4. Secure Android ID

เมื่อ android device ถูกเปิดใช้งานจะมีการ random ค่าและเก็บไว้ ค่านี้สามารถเรียกใช้ได้ผ่าน Settings.Secure.ANDROID_ID ซึ่งค่าที่ได้จะเป็นชุดตัวเลขที่ถูกเก็บไว้ไม่เปลี่ยนจนกว่าจะมีการ reset factory และอย่างที่รู้กันมี bug จากผู้ผลิตซึ่งส่วนใหญ่เป็นกับโทรศัพท์ที่เป็นรุ่นยอดนิยม ทำให้บางครั้งมี ANDROID_ID ซ้ำกัน

String androidId = Settings.Secure.getString(getContentResolver(),
Settings.Secure.ANDROID_ID);

5. UUID

ใช้ function UUID.randomUUID() เพื่อสร้างชุดตัวเลขที่ไม่ซ้ำ (แต่ละเครื่องจะไม่ซ้ำกัน) เพื่อใช้กำหนดตอนติดตั้งแอพพลิเคชั่น แต่เราจำเป็นต้องเก็บค่าไว้ใน local storage เอง และสามารถใช้ Android Backup service ในการเก็บ Unique ID นี้เพื่อสามารถนำไปใช้กับเครื่องอื่นได้ด้วย

Android Backup service https://developer.android.com/google/backup/signup

ref: https://medium.com/@ssaurel/how-to-retrieve-an-unique-id-to-identify-android-devices-6f99fd5369eb


การสร้างข้อความแบบเว้นบรรทัดใน javascript es6 ทำได้ง่ายขึ้นกว่าเดิมโดยการใช้ เครื่องหมาย ` แทน double quote เพียงเท่านี้ก้จะได้ข้อความเว้นบรรทัดแล้ว

ES5 -> var str = “Hello\n World. \n Java Script”;ES6 -> const str = `Hello 
World.
Java Script`;
This is a same results;

rest parameters มีประโยชน์ในการทำให้รับค่า parameter กลายเป็น array และ การรับค่าของ function ก็จะ dinamic ขึ้นด้วย (ไม่จำเป็นต้องประการตัวแปร Array ก่อนนั่นเอง) ดังตัวอย่าง …params คือ rest parameters

function showArray (…params) {
let result = 0;
params.forEach(function(value) {
result += value;
});
console.log(result);
}
showArray(1,2,3,4);output: 10 // 1 + 2 +3 + 4 = 10

Computed

ใน view เราสามารถสร้าง expressions ในการแสดงผลข้อมูลง่ายๆได้โดยการเขียนไปใน html ได้เลย เหมือนกับ AngularJs เช่น

<div id="example">
{{ message.split('').reverse().join('') }}
</div>

แต่มันจะเป็นการซ้ำซ้อนเมื่อเราต้องการเรียกใช้ logic นี้ในการแสดงในส่วนอื่น ดังนั้นเราควรไปสร้างไว้ใน computed ซึ่งจะทำให้สามารถ reuse และแก้ไข ได้ง่าย

computed: {
// a computed getter
reversedMessage: function () {
// `this` points to the vm instance
return this.message.split('').reverse().join('')
}
}

โครงสร้างของ function ใน computed จะต้องมี return เสมอ
( method ต่างจาก compute คือ compute จะทำการ caching ค่าเอาไว้ หาก reactive model ใน compute ไม่มีการเปลี่ยนแปลง )

การเรียกใช้ compute function ใน html

<div id="example">
<p>Original message: "{{ message }}"</p>
<p>Computed reversed message: "{{ reversedMessage }}"</p>
</div>

Watchers

ในบางครั้งที่เราต้องการ event หลังจากที่ตัวแปรที่เราสนใจมีการเปลี่ยนแปลงค่า ดังนั้น watch จะตอบโจทย์ในเรื่องนี้ และ watch ยังเหมาะกับการที่ทำงานเกี่ยวกับ asynchronous หรือ การ…


เมื่อมีการทำงานเกี่ยวกับ Asynchronous Fuction

Asynchronous Fuction คือ function ที่เราสั่งให้มันทำงานแล้ว ไม่รอให้ทำงานเสร็จก่อน ถึงจะไปทำงานใน function ถัดไป ซึ่งผลลัพธ์ของ function แบบนี้นั้นจะกลับมาด้วยสิ่งที่เราเรียกว่า callback ตัวอย่างเช่น

function sum (num1, num2, callback) {
setTimeout(function () { callback(num1 + num2); }, 1000);
}

sum(1, 2, function (result) { console.log(result); });

จากโค๊ดข้างบนคือ ผลลัพธ์จะแสดงออกมาหลังจาก 1sec ที่เรียกใช้ function และผลลัพธ์ที่ได้จะกลับมาที่ function(result){ console.log(result) } function นี้จะเรียกว่าเป็น callback function ที่รอผลลัพธ์กลับมาคือ result และแสดงค่าออกมาคือ 3 นั่นเอง แล้วถ้าอยากเอาผลลัพธ์ที่ได้ไปบวกต่อหละ ก้ทำได้โดย

sum(1,2,function(result){
const myResult = result; // myResult = 3
sum(myResult,3,function(result){
console.log(result) // result = 6
})
})

จากโค๊ดด้านบนจะได้ผลลัพธ์เท่ากับ 6 แต่สังเกตุว่าโค๊ดจะดูค่อนข้างลำบากหากเราต้องการนำผลลัพธ์ที่ได้จาก callback ไปดำเนินการต่อหลายๆครั้ง เช่น

sum(1,2,function(result){ const myResult = result; sum(myResult,3,function(result){ const myResult = result; sum(myResult,4,function(result){ const myResult = result; sum(myResult,5,function(result){ console.log(result) })…

Panya.Bas

{ เขียนไว้เพื่อกลับมาอ่านกันลืม }

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store