Archive

Archive for the ‘Programming’ Category

ทำไงให้ใช้ Selenium บน ras pi ได้

July 4th, 2018 Comments off

หลังจากลองผิดลองถูกมานาน ซื้อบอร์ด x86 มาทิ้งไว้เฉย ๆ ไปอันนึง ด้วยความที่เหมือนมันจะกินไฟเยอะแฮงค์บ่อย
จนต้องวางไว้เฉย ๆ สุดท้ายก็ต้องลงหา ras pi มาลง Selenium ซึ่งปัญหาเยอะกว่าเพราะเป็น ARM

สรุปเลย สูตรคือใช้ Selenium + Firefox + geckodriver ลงตามนี้ครับทดสอบแล้วว่าใช้ได้แน่ ๆ

sudo pip install selenium

sudo apt-get install firefox-esr

ทีนี้ geckodriver จะใช้ version ล่าสุดไม่ได้ครับให้ไปโหลดตัวนี้มา

น้ำตาแทบไหลกว่าจะทำได้

พอลองแล้วติดตรงตัว Firefox 52 ทำ headless ไม่ได้เวลาทำ cronjob ไว้จะขึ้นเชื่อมต่อไม่ได้วิธีแก้นะครับ
ให้ลง pyvirtualdisplay กับ xvfb ก่อน

pip install pyvirtualdisplay

sudo apt-get install xvfb

แล้ว import ตัว Display หลอกให้ python output ไปออกใน pyvirtualdisplay ด้วย

from pyvirtualdisplay import Display

display = Display(visible=0, size=(800, 600))
display.start()

มันก็จะ run ใน cronjob ได้ครับ

Categories: Programming Tags:

อ่านบัตรประชาชน smartcard โดยใช้ python

February 8th, 2015 8 comments

ผมเขียนเรื่องนี้สำหรับเป็น guideline สำหรับคนที่อยากอ่านข้อมูลในบัตรประชาชนนะครับ

ข้อมูลทั้งหมดได้มาจากคุณพุฒิพงศ์ ซึ่งเป็นคนพัฒนาโปรแกรม นี้ ครับ

ผมเมลไปถามแกหน้าด้าน ๆ เลยครับว่าทำยังไง แกก็ตอบมาแบบละเอียดเลยครับ

เลยไหน ๆ ก็ไหน ๆ ละขอเขียนทิ้งไว้ก็แล้วกันครับเผื่อมีคนอยากทราบวิธี

ผมใช้ lib ของ python pyscard ครับ วิธีการใช้ดูจาก documentation เลยครับ

ตัวอย่างเป็นการอ่านข้อมูลในส่วน public ของ smart card

# -*- coding: cp874 -*-
from smartcard.CardConnection import CardConnection
from smartcard.CardType import AnyCardType
from smartcard.CardRequest import CardRequest
from smartcard.util import toHexString, toBytes

import ธรรมดาครับ

cardtype = AnyCardType()
cardrequest = CardRequest( timeout=1, cardType=cardtype )

cardservice = cardrequest.waitforcard()

cardservice.connection.connect()

เชื่อมต่อไปยัง reader ดูว่ามีการ์ดเสียบอยู่นะ

SELECT = [0x00, 0xA4, 0x04, 0x00, 0x08]
THAI_ID_CARD = [0xA0, 0x00, 0x00, 0x00, 0x54, 0x48, 0x00, 0x01]
REQ_CID = [0x80, 0xb0, 0x00, 0x04, 0x02, 0x00, 0x0d]
REQ_THAI_NAME = [0x80, 0xb0, 0x00, 0x11, 0x02, 0x00, 0x64]
REQ_ENG_NAME = [0x80, 0xb0, 0x00, 0x75, 0x02, 0x00, 0x64]
REQ_GENDER = [0x80, 0xb0, 0x00, 0xE1, 0x02, 0x00, 0x01]
REQ_DOB = [0x80, 0xb0, 0x00, 0xD9, 0x02, 0x00, 0x08]
REQ_ADDRESS = [0x80, 0xb0, 0x15, 0x79, 0x02, 0x00, 0x64]
REQ_ISSUE_EXPIRE = [0x80, 0xb0, 0x01, 0x67, 0x02, 0x00, 0x12]

DATA = [REQ_CID,REQ_THAI_NAME,REQ_ENG_NAME,REQ_GENDER,REQ_DOB,
REQ_ADDRESS,REQ_ISSUE_EXPIRE]

ตรงนี้เป็นคำสั่งในการขอข้อมูลครับ คือ ขั้นตอนการขอข้อมูลจากการ์ดจะเป็น

1. ฉันจะอ่านบัตรประชาชนนะนายใช่บัตรประชาชนรึเปล่า
2. บัตรตอบมาว่าใช่หรือไม่
3. โอเค ฉันอยากได้ข้อมูลเลข 13 หลักที่มีความยาว x
4. บัตรตอบกลับมาว่าฉันมีข้อมูลนี้ ยาว x
5. ขอดูข้อมูลหน่อยละกัน
6. บัตรส่งข้อมูลให้

apdu = SELECT+THAI_ID_CARD
f = open(‘temp.txt’,’w’)

response, sw1, sw2 = cardservice.connection.transmit( apdu )
#print ‘response: ‘, response, ‘ status words: ‘, “%x %x” % (sw1, sw2)

อันนี้เป็นข้อ 1-2 ครับ ดูตรง sw1 กับ sw2 ครับ ถ้าโอเคจะตอบกลับมาเป็น

0x90 xx หรือ 0x61 xx ซึ่ง 90 คือโอเค ส่วน 61 คือ โอเคแต่มีข้อมูล xx ไบต์นะ

#print ‘response: ‘, response, ‘ status words: ‘, “%x %x” % (sw1, sw2)
for d in DATA:
response, sw1, sw2 = cardservice.connection.transmit( d )
print sw1
if sw1 == 0x61:

ไล่ขอข้อมูลใน list DATA ส่วนนี้สังเกตว่าบัตรตอบกลับมาว่า 0x61 มีข้อมูลอีก xx นะ
เริ่มจาก cid

GET_RESPONSE = [0X00, 0XC0, 0x00, 0x00 ]
apdu = GET_RESPONSE + [sw2]

ตรงนี้ขอดูข้อมูลที่บอกว่ามีหน่อย

print ‘sending ‘ + toHexString(apdu)
response, sw1, sw2 = cardservice.connection.transmit( apdu )
print ‘response: ‘, toHexString(response), ‘ status words: ‘, “%x %x” % (sw1, sw2)
result = “”
for i in response:
result = result+chr(i)
f.write(result.strip()+”\n”)

ส่วนนี้แค่ไล่อ่านจนครบทุกข้อมูล จริง ๆ จะมีรูปภาพอีกครับแต่ไม่ได้ทำไว้เพราะอายุบัตรค่อนข้างนาน

รูปในบัตรจะดูห่างจากตัวจริงเยอะไป


Categories: Programming Tags: