Pages

12/28/2010

Plasma Speaker

วันนี้เพิ่งจะเห็นว่ามีคนเอา plasma มาทำเป็น speaker จริงๆแล้ว  (ความจริงอาจจะทำไว้นานแต่เราไม่รู้ก็ได้)  นี่เป็นวีดีโอที่เขาทำเอาไว้บรรเลงเพลงชื่อ Bloody Well Right.



หลักการที่เขาเขียนไว้ก็คือ  เส้นพลาสม่าที่เห็นเนี่ย จริงๆแล้วมันสร้างความถี่สูงออกมาเท่านั้น สูงแค่ไหน? ก็ราวๆ 30,000 Hz ซึ่งหูมนุษย์ฟังเสียงได้สูงสุดแค่ 20,000 Hz  ก็ไม่มีทางฟังเสียงนั้นออกอยู่แล้วแต่ถ้า เราเอาเสียงนี้มาปิดๆเปิดๆ 1000 ครั้งต่อนาที เราก็จะได้ยินเสียง 1000Hz รึเปล่า   ที่เหลือก็แค่เอาเพลงมาเิปดและทำให้พลาสม่านี้เปิดปิดตามความถี่ของเพลงเท่านั้น

ถ้าจะเอาในรายละเอียด   การสร้างเสียงด้วย plasma ซึ่งมีเสียงที่หูไม่ได้ยินอยู่นั้น  ทำได้โดยใช้วิธี Amplitude Modulation(AM) ลงไป  เพราะเมื่อความถี่สูงที่หูไม่ได้ยินนั้นถูกครอบด้วย envelope ที่เป็นเสียงที่คนเราได้ยินได้   มันก็จะมีรูปคลื่นออกมาเป็นคลื่นเสียงแบบที่เห็นข้างล่าง และเวลาฟังหูเราก็จะทำการตัดความถี่สูงที่ไม่ได้ยินออกไปโดยอัตโนมัติ  ก็จะทำให้ได้ยินเสียงนั้น
แต่จะทำให้พลาสม่ากลายเป็น AM ได้ยังไง   อันนี้ก็ต้องพึ่ง pulse-width-modulation (PWM)ละ
เนื่องจาก plasmaเองไม่ใช่ความถี่  แต่ถ้าเปิดเครื่องplasma ถึงจะเกิดความถี่มาด้วย  ดังนั้นก็เลยต้องใช้วิธีควบคุมการเปิดปิดเครื่องแทน รวมถึงความถี่ห่างของการเปิดปิดเครื่องplasma
PWMจึงเหมาะในการเข้ามาทำตรงนี้
จากรูปคือเมื่อเสียง(สีเขียว)เข้ามา จะถูกsamplingด้วยความถี่ๆนึง(สีน้ำเงิน) และจุดที่ตัดกันของสัญญาณทั้งสอง ก็จะมาถูกคำนวนกลายเป็นสัญญาณ PWM
ซึ่งในเคสนี้ ก็คือเราเอามาใช้เปิดปิด plasma   ดังนั้นถ้าสัญญาณPWMมันเป็นแท่งใหญ่ (ช่วง1ยาว) ก็จะได้สัญญาณAMที่มีAmplitudeสูง  ตรงกันข้ามกับช่วงไหนที่สัญญาณPWMเป็นแท่งบางๆ (ช่วง0ยาว) ก็จะทำให้ได้Amplitudeของสัญญาณเสียงที่ออกมามีAmplitudeต่ำไปด้วย

สรุปก็คือง่ายๆ    เสียงเข้ามา---> Sampling ---> ทำเป็น PWM --->นำไปขยาย--->เอาไปใช้เปิดปิด Tesla coil--->สร้างplasma ---> ทำให้เกิดเสียง(จากสัญญาณAM)

นี่เองที่ทำไมในวงจรเลยต้องมี PWM IC (เอาไว้สร้างPWM) กับ MOSFET Transistor (เอาไว้ขยายPWMให้เป็นสัญญาณเปิดปิดTesla)

ตอนนี้กำลังอยู่ว่าใครจะเอา ลำโพงที่ทำด้วยPlasmaแบบนี้มาเล่นเพลงนี้บ้าง   จะได้เหมือนกับหนังเรื่อง The Sorcerer's Apprentice

Secret: One Republic




Ref:
 - Circuit & VDO : http://teravolt.org/Plasma_Speaker_2.htm
 - Pictures: Wikipedia.org

Additional (ถามเอง ตอบเอง):
  Q: ถ้าเราสามารถได้ยินเสียงที่เข้ารหัสแบบAMได้โดยตรง ถ้าความถี่ของcarrier signalสูงมากๆจนไม่ได้ยิน  แล้วทำไมเราไม่ได้ยินเสียงจากคลื่นวิทยุ AM ตลอดเวลา?
  A: เพราะ carrierของวิทยุAMคือ electromagnetic signal ไม่ใช่ sound signal ดังนั้น เราต้องแปลงจากElectromagnetic signal นี้ให้อยู่ในรูป sound signal ซะก่อน   ซึ่งอุปกรณ์ตัวนั้นก็คือ  "ลำโพง"

  Q: ถ้างั้นถ้าตั้งลำโพงไว้เฉยๆ  มันก็ดังเองได้สิ?
  A: ก็คงต้องต่อ ground ไว้ขานึงด้วย และอีกขานึงต่อเข้ากับAM signal ที่โดนกรองให้เหลือแค่ช่องสัญญาณเดียวแล้ว   และนั่นก็กลายเป็นวิทยุแร่นั่นเอง http://www.hs8jyx.com/images/article/102.gif

  "Tremolo" ที่เห็นในกีตาร์เอฟเฟกท์ คือ การใช้ Amplitude Modulation เข้ากับสัญญาณเสียง  เพียงแค่ว่าคราวนี้ carrier signal มันมีความถี่ที่ช้ามากๆ  ทำให้เรารู้สึกถึงenvelopeที่ครอบสัญญาณเสียงได้เลย

12/23/2010

Skype is Down

เมื่อวานทั้งวัน เกิดปัญหาขึ้นกับผู้ใช้ Skype (เราก็โดนด้วย)
นั่นคือ Skype ไม่สามารถ sign-in เข้าไปได้

  


เพิ่งอ่านข่าวเจอแล้วก็รู้ว่า ปัญหานี้กระทบกับคนทั่วทั้งโลกเลยด้วย
ซึ่งไม่น่าจะเป็นไปได้  เพราะว่า Skype นั้นปกติใช้ระบบ p2p เพื่อเชื่อมต่ออยู่แล้ว
ระบบ p2p นั่นก็คือ การเชื่อมต่อการสื่อสารจาก เครื่องต้นทาง>>>ผ่านเครื่องผู้ใช้skypeคนอื่นเรื่อยๆ>>>ไปจนถึงปลายทาง  ซึ่งถ้าเครื่องผู้ใช้อื่นๆไม่ล่ม ระบบp2pแบบนี้ก็ไม่น่าจะล่มด้วย

แต่สาเหตุเกิดขึ้น ทางSkypeเปิดเผย(ตั้งแต่วันพุธบ่าย)ว่า การเชื่อมต่อเข้ากับระบบของผู้ใช้เข้าสู่คอมพิวเตอร์ของSkypeเรียกว่า "Supernodes" นั้นมีปัญหา ทำให้ผู้ใช้ไม่สามารถต่อเข้ากับระบบP2Pเลยจะไม่รู้ว่าจะมีเครื่องอื่นๆให้เชื่อมต่อไปหาได้  เพราะSkypeกำลังจะสร้างระบบ mega-supernodes ขึ้นมาใหม่  โดยทางSkypeจะแก้ให้เสร็จให้เร็วที่สุด และสามารถติดตามข่าว update ได้ที่twitter  @skype




ล่าสุดจนถึงตอนนี้(พฤหัสเช้า) จากที่ทดลองเอง ระบบก็ยังติดๆดับๆ ยังไม่สามารถต่อเชื่อมได้ตลอดเวลาเหมือนเดิม

ref:
http://www.skype.com/intl/en-us/StatusUpdate/
http://www.cnn.com/2010/TECH/web/12/23/skype.outage/index.html

12/22/2010

The Tourist (2010)

/*----- เนื้อหาข้างล่างนี้มีสปอยล์แน่นอน ถ้าไม่อยากรู้ก็กรุณาอย่าอ่านต่อ ------*/
แค่โปสเตอร์หนังก็แปลกละ..  เดี๋ยวนี้แองเจลินาโจลี่ มีเคราแล้วเหรอ 555


The Tourist 

ชื่อไทยคือ "ทริปลวงโลก"  <---- ตั้งเข้าไปได้ไงเนี่ย!!!!
เพิ่งได้ดูมาวันนี้ สนุกมาก เลยดูเข้าไปสองรอบแล้ว 5555

บอกตรงๆว่าเป็นหนังที่จะว่า ซึ้ง ก็ไม่ซึ้ง,  จะมีแอ๊คชั่นก็ไม่ใช่ว่าจะแอ๊คชั่นมากมาย, จะหวานก็ไม่ได้หวานมาก, แถมยังทำให้ลึกลับนิดหน่อยมีปริศนาอยู่ตลอดเรื่องด้วย  อ้อยังต้องบ่นเรื่องCGตัดต่อไม่เนียนเท่าไหร่  แถมยังมีจุดให้จับผิดได้ชัดๆตอนดูเลยด้วย

ซึ่งโดยปกติแล้ว ถ้าดูหนังแบบนี้ที่ว่าไม่มีอะไรโดดเด่นซักอย่างนี่ น่าจะให้คะแนนน้อย แล้วก็ไม่อยากดูอีก    แต่หนังเรื่องนี้มีอะไรมีสเน่ห์ซักอย่างให้ได้ดูได้อีกรอบ  

ไม่รู้ว่าเป็นเสน่ห์ของเมือง Paris และ Venice รึเปล่า ที่ดูทิวทัศน์ต่างๆของเมืองแล้วสวยมาก    ยิ่งถ้าใครรู้จักเกม Assassin Creed2 แล้ว  มีฉากที่พระเอกวิ่งหนีผู้ร้ายบนหลังคาบ้านเมืองVenice นี่เหมือนกันเด๊ะๆเลย    รวมถึงเพลงบรรเลงที่มีเปิดคลอๆไปตลอดทั้งเรื่อง (เหมือนว่าจะเป็นละครเพลงรึเปล่านะ?  เอ๊ะไม่ใช่นี่นา)   แล้วที่เด็ดสุดเนี่ย  พล๊อตเรื่องเลย!  ดูแล้วก็แบบว่า  อื้มๆ.. อื้อๆ...อือ..... อ้าวเฮ้ย!!! อะไรฟะ???   เลยเป็นที่มาของต้องไปดูอีกรอบนึง

มาเข้าเรื่องดีกว่า  แต่ก็จะต้องเกริ่นเรื่องตัวละครก่อน เริ่มจาก  Ellis Clifton-Ward (Angelina Jolie) หญิงสาวผู้รสนิยมสูง  (แล้วก็ทำตัวเชิดตลอดเวลา)  ได้ถูกตำรวจScotland Yardของอังกฤษ โดยมีหัวหน้าสายสืบคือ John Acheson(Paul Bettany) ตามสอดส่องพฤติกรรมตลอดเวลา  เนื่องจากว่า Ellis เป็นเบาะแสคนเดียวที่มีสายสัมพันธ์กับอาชญากรข้ามชาติ ที่ประเทศกว่า 14 ประเทศต้องการตามตัวอยู่ คนๆนั้นคือ Alexander Pierce 

คดีต่างๆที่ Pierce ทำก็คือ เชิดเงินแก๊งอาชญกรต่างๆ แล้วก็หนี  ทำให้เขากลายเป็นที่ต้องการตัวของทั้งอาชญากรต่างๆและก็ตำรวจด้วย   แต่โชคยังดีที่ไม่เคยมีใครเคยเห็นหน้าตาของ Pierce มาก่อน เลยทำให้เขายังไม่ถูกจับ  ยกเว้น... เธอคนนั้นที่ชื่อ Ellis แฟนของPierce

เรื่องเริ่มต้นจากฉากในกรุงปารีส   ให้เห็นว่า ทุกท่าทางEllisทำ  ทุกที่ๆEllisไป จะต้องมีสายตำรวจนอกเครื่องแบบแอบสังเกตพฤติกรรมอยู่ตลอดเวลา   และแล้ววันนี้... ก็เป็นวันที่Ellisได้รับจดหมายจากPierceหลังขาดการติดต่อมาสองปี  ที่ร้านอาหารร้านหนึ่ง

ในจดหมายนั้นเขียนว่า...  "Ellis, คุณไม่มีเหตุผลที่จะเชื่อใจผมอีกต่อไปแล้วก็จริง  แต่ขอให้ผมได้อธิบายให้ฟังก่อน  ผมรู้ว่าคุณกำลังถูกตำรวจเฝ้ามองอยู่  เราต้องทำให้พวกนั้นตามเราไม่ได้ก่อน  แล้วให้ขึ้นรถไฟเที่ยวเวลา8.22 ที่ Garden Lyon  แล้วหาใครซักคนที่สูงเท่ากับผม หุ่นเดียวกับผม แล้วก็ทำให้ตำรวจเชื่อว่าเป็นผม.... แล้วก็เผาจดหมายนี้ทิ้ง  สำคัญมากคุณต้องทำตามที่ผมเขียน  ผมรักคุณ...  Alexander"  
Ellis ก็ได้ทำตามทุกอย่าง   ทั้งเผาจดหมาย  ทั้งสลัดตำรวจที่ติดตามทิ้ง  แล้วก็ขึ้นรถไฟเที่ยว8.22ที่Garden Lyon ไป Venice   รวมถึง หาคนที่หุ่นแบบเดียวกับAlexanderบนรถไฟด้วย

นี่เองที่เป็นการพบกันครั้งแรกของ Ellis และ Frank

Ellis มาเจอกับ Frank Tupelo (Johnny Depp) บนรถไฟ แล้วก็กะจะให้ Frank สวมรอยเป็น Alexแทนเพื่อหลอกตำรวจให้หลงกล   ในขณะที่ Frank ก็คิดว่าโชคดีจริงๆที่ได้มาเจอกับผู้หญิงสวยขนาดนี้ แล้วทั้งสองก็เริ่มพูดคุยกัน  ทำให้รู้ว่า Frank เป็นครูสอนเลขที่มาจากWisconsin, USA กำลังอยู่ในช่วงอดบุหรี่และเคยมีแฟนตายไปเมื่อสามปีแล้วในเหตุรถชน   แต่พวกนี้ก็แทบจะตรงกันข้ามกับ Ellisหมดเลย  เธอหยิ่ง มีสไตล์ ลึกลับ และชอบผู้ชายที่มีความเป็นตัวของตัวเองสูง 

ในขณะที่ ทั้งสองกำลังนั่งรถไฟไป Venice, ทาง John ก็ได้นำซากของจดหมายที่ถูกเผามาแกะร่องรอย   ก็พบแผนทั้งหมดที่เขียนไว้ในจดหมายนั้น  รวมถึงรู้ว่า Frank คนที่อยู่กับEllisตอนนี้เป็นเพียงแค่ตัวแทนที่Ellisเอามาหลอกตำรวจเท่านั้น  ดังนั้นทางตำรวจก็ต้องตามตัวEllisต่อไป เผื่อจะเจอว่าAlexจะเข้ามาหาEllisในเมืองVenice

แต่เรื่องไม่จบที่ตรงนี้ ในscotland yard มีตำรวจที่เป็นสปายให้กับกลุ่มอาชญากรรัสเซียด้วย  พอตำรวจคนนั้นรู้แค่ว่าEllisมีผู้ชายอยู่ด้วย  และไม่ได้เห็นจดหมาย  ก็เลยนึกว่าคนที่อยู่ด้วยกับEllisนี้เป็นAlex  เลยแจ้งให้ทางกลุ่มอาชญากรรัสเซียนั้นรู้  Mr. Shaw หัวหน้าของพวกนี้ก็เลยตามกะจะไปจัดการกับAlexที่Venice  เพราะคดีล่าสุดของAlexคือการขโมยเงินจากกลุ่มนี้ไปหลายพันล้าน

พอถึงVenice, ... เพื่อความเนียน Ellisก็เลยได้อยู่ห้องเดียวกับFrank รวมถึงทานdinnerด้วยกัน ไปไหนด้วยกัน แลกเปลี่ยนเรื่องราวส่วนตัวมากขึ้น (รวมถึงเรื่องAlex Pierceด้วย)  ความที่ใช้เวลาอยู่ด้วยกันมากขึ้น  ก็เลยเริ่มก่อตัวเป็นความรัก  แต่ด้วยความเข้าใจผิดของกลุ่มรัสเซียที่จ้องจะจับตัวAlex  ทำให้Frank(ที่คนคิดว่าAlex) โดนไล่ล่าไปด้วย  จนต้องหนีตายจากกลุ่มนั้น  ทั้งวิ่งบนหลังคาบ้าน ทั้งกระโดดตึก ทั้งหนีจากการไล่ล่าทางเรือ จนต้องให้Ellisช่วยออกมา  .... ตอนนี้ถึง Ellisจะเริ่มชอบFrankแล้ว  แต่ก็มีความสงสารที่ไม่อยากให้Frankต้องมาเป็นเครื่องมือของเธออีก  จนEllisตัดสินใจพาFrankไปส่งที่สนามบินเพื่อให้บินกลับอเมริกาไป   แต่Frankก็หลงรักเธอเข้าไปแล้วเหมือนกัน ก็เลยจะกลับไปหาEllisให้ได้  ถึงแม้จะต้องฝ่าดงกระสุนไปก็ตาม

และแล้วปริศนาอย่างนึงก็คลายออกมา ว่าทำไมEllisต้องเข้าไปพัวพันธ์กับ Alex ผู้เป็นอาชญากรด้วย  ก็เพราะEllisเป็นตำรวจนอกเครื่องแบบเพื่อมาจับAlex  แต่แล้วก็หนีตามAlexไปไม่แม้แต่จะส่งรูปหน้าตาของAlexกลับมาให้กรม  แต่ในที่สุดหลังจากเจอว่าคนบริสุทธิ์อย่างFrankจะต้องโดนไล่ล่าแล้ว เธอก็ตัดสินใจที่จะส่งตัวAlexให้กลับกรมตำรวจ   ซึ่งจดหมายล่าสุดของAlexบอกว่าให้Ellisไปที่งานบอลลูม  ทางตำรวจก็คาดว่าจะจับตัวAlexที่งานนี้ได้

Ellis ก็เลยต้องไปงานนี้, ตำรวจJohn ก็ไปงานนี้, Frank ด้วยความที่อยากเจอEllisก็ไปงานนี้, และพวกมาเฟียรัสเซียก็ตามติดEllis ก็ไปที่งานนี้เหมือนกัน

จะเกิดอะไรขึ้น จะจบอย่างไง ขี้เกียจเขียนละ... แต่อย่างน้อยก็จบดีละกัน happy ending :)



12/20/2010

Interesting Education Idea

RSA Animate - Drive: The surprising truth about what motivates us



RSA Animate - Changing Education Paradigms

12/17/2010

Remove PulseAudio, Install Alsa

ว่าจะไม่อยากเปลี่ยนแล้วนะ  เพราะว่า Pulse Audio ที่ติดมากับ Ubuntu ในหลายๆรุ่น (รวมถึงตัวล่าสุดด้วย)
แต่ก็ทนกับปัญหาของ pulse audio ไม่ไหวแล้วจริงๆ จะเคลียร์  555
ทั้งปัญหากินแรมเยอะ  เปิดกับ flash กับอะไรอื่นๆหน่อย ก็ค้าง (ที่ค้างนี่คือมัน down cpu speed ทำให้ทุกอย่างรันช้าลง)   ยิ่ง cache เต็มปุ๊ปยิ่งเห็นผลเลย
แถมยังมีปัญหากับ Skype อีก   แบบว่า sound effect ทุกอย่างของskypeไม่มีเสียงเลย  แล้วก็ไม่สามารถเลือกdeviceเสียงได้ด้วย  ต้องเลือกเป็นpulseaudioอย่างเดียว

หลังจากติดแหง็ก กับปัญหาดังกล่าวข้างต้นมาหลายเดือน ในที่สุดวันนี้ก็ตัดใจ เอา pulseaudio ออกซักที
ก็ไปไล่ตามวิธีตามเวปต่างๆดังนี้





หลายๆเวปเหล่านี้ก็บอกวิธีออกมาคล้ายๆกัน  แต่ทำทั้งหมดเลยเพื่อความสมบูรณ์
ตั้งแต่
# pulse เอาออก
sudo apt-get purge pulseaudio gstreamer0.10-pulseaudio
sudo apt-get autoremove

# ใส่ Alsa ลงไป
sudo apt-get install alsa-base alsa-tools alsa-tools-gui alsa-utils alsa-oss linux-sound-base alsamixergui
sudo apt-get install esound esound-clients esound-common libesd-alsa0 gnome-alsamixer
sudo apt-get install python python-notify python-gtk2 python-alsaaudio python-eggtrayicon xfce4-mixer

#configure
gstreamer-properties  #รันคำสั้งนี้ เพื่อแก้ input/output แก้ให้เป็น ALSA
wget http://www.playoss.com/sites/default/files/alsa_mixer_applet.tar_.gz #โหลดไฟล์ด้วย wget
tar xvf alsa_mixer_applet.tar_.gz
#เอาทุกไฟล์ในนั้นไปลง /usr/local/bin แล้วก็ตั้งทุกอย่างให้เป็น chmod 755
#แล้วก็เอา /usr/local/bin/volbar.py กับ /usr/local/bin/alsavol.py ไปใส่ไว้ใน Startup เพื่อให้รันตอนเปิดเครื่อง
#แล้วก็ ตั้ง keyboard shortcut ใหม่ให้ปุ่ม mute,vol up, vol down  ไปสั่งรันที่ /usr/local/alsa_master_mute , /usr/local/alsa_master_up , /usr/local/alsa_master_down

เวลาจะรัน mixer ก็เลือกได้ว่าจะใช้ gnome-alsamixer หรือว่าจะใช้ xfce4-mixer (อันหลังเหมือนจะสวยกว่า)

ขาดเหลืออะไรก็ดูที่ URL ด้านบนเพิ่ม

xfce4-mixer

gnome-alsamixer

volbar.py

alsavol.py


update:
 - ถ้าเครื่องมีหลายๆ Mic ให้ลองใช้ Audacity ทดสอบอัดเสียงจากทีละไมค์ จะได้รู้ว่าอันไหนทำให้เสียงออก    ถ้ามีปัญหาก็ต้องลองเปิดตัวmixerขึ้นมาตั้งค่าswitchต่างๆดู
 - สำหรับ Dell XPS1330: จะขึ้นว่ามี 3 ไมค์   แต่ไมค์ที่ใช้ได้สำหรับช่องเสียบออกด้านหน้าเครื่องคือ  Mic0:

12/16/2010

ClubHack

วันนี้เพิ่งเปิดเน็ตไปเรื่อยๆ แล้วก็เจอชื่อกลุ่มๆนึงที่น่าสนใจ ก็เลยเอามาเขียนแนะนำคร่าวๆ





กลุ่มนี้มีชื่อว่า ClubHack

ClubHack ตามคำอธิบายที่หน้าเวป http://clubhack.com อธิบายตัวเองไว้ว่า
เป็นกลุ่มที่ไม่แสวงหาผลประโยชน์ โดยมีจุดมุ่งหมายเพื่อให้ผู้คนตื่นตัวเรื่องความปลอดภัยมากขึ้น
โดยกลุ่มนี้ เริ่มต้นมาจาก การจัดสัมมนาทางด้านsecurityในประเทศอินเดีย
แต่ตอนนี้ก็เริ่มสร้างสื่อต่างๆออกมามากมาย ทั้ง นิตยสารรายเดือน (e-magazine)
มี twitter, facebook page, friendfeed, youtube, slideshare, ... และอื่นๆอีกมากมาย

แต่ถึงจะเป็นกลุ่มจากประเทศอินเดีย ที่เน้นเป็นศูนย์กลางของผู้สนใจทางด้านcomputer securityคล้ายๆกับกลุ่ม CITEC ของไทยเหมือนกัน   แต่ก็ยังมีข้อแตกต่างกันอยู่หลายด้าน
เช่น ของอินเดียไม่มีforumไว้สนทนา, เน้นเอาผลงานออกมาเป็นpublication paper มาพรีเซนต์มากกว่า, แล้วก็ออกมาในรูปแบบconference เป็นต้น

แต่ถึงยังไงก็ตาม  เอาเป็นว่าเราสนใจว่ามีอะไรให้เรียนรู้บ้างดีกว่าเนอะ

ที่ดูแล้วเด็ดๆ ที่ค้นๆได้จากในเวปก็คือ

  • Youtube : http://www.youtube.com/view_play_list?p=972A9CD8D9E87959 มีวีดีโอทำมือจากสมาชิกClubHackเอง มีอยู่หลายตัวเหมือนกัน
  • SlideShare : http://www.slideshare.net/clubhack มีสไลด์ประกอบคำบรรยาย (คาดว่ามาจากงานสัมมนา) มีอยู่เยอะเหมือนกัน  และTopicแต่ละตัวก็ใช้ได้เลย
  • E-Magazine : http://chmag.in/  นิตยสารรายเดือน จัดทำโดย ClubHack และจัดว่าเป็น "1st indian Hacking magazine"

เวปไซต์อื่นๆที่เกี่ยวข้อง


Practical use of Metasploit's msfpayload and msfencode command

Read this paper:
Title: Effectiveness of Antivirus in Detecting Metasploit Payloads
GCIH Gold Certification
Author: Mark Baggett
URL: http://www.giac.org/certified_professionals/practicals/GCIH/01072.php
Year: 2008

12/15/2010

Mantra

"Mantra is a dream that came true. It is a collection of free and open source tools integrated into a web browser, which can become handy for students, penetration testers, web application developers, security professionals etc. ..."

"... Mantra is lite, flexible, portable and user friendly with a nice graphical user interface. You can carry it in memory cards, flash drives, CD/DVDs, etc. It can be run natively on Linux, Windows and Mac platforms. It can also be installed on to your system within minutes. Mantra is absolutely free of cost and takes no time for you to set up."
http://www.getmantra.com/

หลังจากอ่านดูแล้ว  ตัวโปรแกรม Mantra นี่ก็น่าสนใจดีนะ  ไหนลองไปดาวน์โหลดมาลงดูซิ


อื้ม...  โหลดได้สองที่ ทั้งจาก SourceForge และ Google App เลย ใช้ได้ๆ   นี่แสดงว่าพร้อมทำเป็น open source software สำหรับ penetration tester โดยตรงเลยสินะ

เนื่องจากเป็นlinux อยู่ก็โหลดแบบ linux มาลองดูละกัน
ได้มาเป็นไฟล์ชื่อ  mantra-portable-pre-alpha.tar.bz2  ก็ใช้คำสั่ง
tar xvf mantra-portable-pre-alpha.tar.bz2 
เพื่อแตกไฟล์

หลังจากแตกไฟล์แล้ว สิ่งที่ได้จะเป็น folder ชื่อ mantra-portable ก็เริ่มเอะใจละ ว่าทำไมมันมีคำว่า portable ด้วยหว่า
ไหนลองเปิดเข้าไปดูซิ ก็เจอไฟล์นี้เลย
~/Downloads/mantra-portable$ ls
app  data  firefox-portable
โอ้ mantra ทำมาจาก portable firefox นี่เอง งั้นก็คงไม่มีอะไรใหม่เท่าไหร่

หลังจากลองรันโปรแกรมขึ้นมา ก็เจอ Error เพียบเลย เพราะว่าโปรแกรม Mantra นี่มีมันเป็น 32Bit ไม่ใช่ 64bit เฮ้อ...
...
LoadPlugin: failed to initialize shared library /usr/lib/mozilla/plugins/libtotem-mully-plugin.so [/usr/lib/mozilla/plugins/libtotem-mully-plugin.so: wrong ELF class: ELFCLASS64]
LoadPlugin: failed to initialize shared library /usr/lib/moonlight/plugin/libmoonloader.so [/usr/lib/moonlight/plugin/libmoonloader.so: wrong ELF class: ELFCLASS64]
detection-plugin.so [/usr/lib/mozilla/plugins/librhythmbox-itms-detection-plugin.so: wrong ELF class: ELFCLASS64]
LoadPlugin: failed to initialize shared library /var/lib/flashplugin-installer/npwrapper.libflashplayer.so [/var/lib/flashplugin-installer/npwrapper.libflashplayer.so: wrong ELF class: ELFCLASS64]
LoadPlugin: failed to initialize shared library /usr/lib/jvm/java-6-openjdk/jre/lib/amd64/IcedTeaPlugin.so [/usr/lib/jvm/java-6-openjdk/jre/lib/amd64/IcedTeaPlugin.so: wrong ELF class: ELFCLASS64]
/usr/lib/gio/modules/libgvfsdbus.so: wrong ELF class: ELFCLASS64
....

แต่ถึงยังไง ก็เข้าหน้าแรกให้ดูกันได้ หน้าของโปรแกรมเป็นแบบนี้

Theme ก็สวยดีนะ ก็ข้างใต้ URL bar มีแถบที่เป็น Acunetic Web Scanner อยู่เลย
ทางด้านตรงกลางเป็น web browser ธรรมดา ไม่มีอะไรใหม่  แค่เปิดมาเป็นหน้าของ Mantra เลยเท่านั้น
ส่วนด้านขวานีี่แหละ ที่สำคัญ ... เพราะเ็นหน้าที่รวมเครื่องมือต่างๆไว้ให้ใช้

ด้านขวานี่ น่าจะใช้ firefox plugin ที่ชื่อว่า All-in-One Sidebar เพื่อให้มี sidebarขึ้นมาทางด้านขวา
โดย sidebarนี้ในแนวนอน ก็แสดงรายชื่อของ firefox extensions ทั้งหมดที่ลงไว้ในbrowserตัวนี้
ส่วนiconเล็กๆในแนวตั้งก็คือ extensions เหล่านั้นแหละ แต่ทำให้เล็กๆเพื่อใ้ห้เรียกใช้สะดวกๆ น่าจะทำจาก TinyMenu
แล้วก็จะเห็นว่ามีบาง extensions ที่เครื่องผมมีปัญหารันไม่ได้  ก็จะขึ้นตัวแดงอย่างที่เห็น

รายชื่อของ extensions ทั้งหมด (จากเวปของ mantra)
  • Access Me : An extension to test for page access vulnerabilities (session tampering)
  • Acunetic Web Scanner : Audit the security of your website
  • Add N Edit Cookies+ : Cookie Editor that allows you add and edit session and saved cookies
  • Firesheep : ????? ไม่เห็นมี
  • FoxySpider : ????? ไม่เห็นมี
  • Google Site Indexer : ????? ไม่เห็นมี
  • CookieSwap : Tool to save and swap out a collection of cookies on the fly
  • Domain Details : Displays Server Type, Headers, IP Address, Location Flag, and links to Whois Reports
  • Firebug : Web Development Evolved
  • Firebug Autocompleter : Firebug command line autocomplete
  • Firecookie : Cookie manager for Firebug. Firebug has to be installed.
  • FireFlash : Firebug extension for Flash
  • FireFTP : FTP Client for Mozilla Firefox
  • FormBug : An extension to Firefox to make dealing with forms easier
  • FoxyProxy : FoxyProxy - Permier proxy management for firefox
  • Greasemonkey : A User Script Manager for Firefox
  • Groundspeed : A Firefox add-on for Web Application Security Testers
  • HackBar : A toolbar that helps you find an test SQL injections
  • Host Spy : Find other sites hosted on a web server
  • HttpFox : An HTTP analyzer addon for Firefox
  • JavaScript Deobfuscator : Shows you what Javascript code gets to run on webpages
  • JSview : View the source code of external stylesheets and javascripts
  • Key Manager : Firefox Add-on for Key Generation, Certificate Enrollment, and Identity and Authority Delegation
  • Library Detector : Detects what javascript libraries are being used on the current page and display the result as icons with detailed tooltips in the statusbar
  • Live HTTP Headers : View HTTP headers of a page and while browsing
  • PassiveRecon : Powerful Security Assessment Target Reconnaissance (Discovery) Tool
  • Poster : A developer tool for interacting with URLs
  • RefControl : Control what gets sent as the HTTP Referer on a per-site basis
  • refspoof : Allows easy spoofing of URL referer(referrer) w/ toolbar
  • RESTClient : A simple RESTFul web service tester client extension for firefox
  • RESTTest : Allows you to issue HTTP requests with your headers and data and examine the results to test REST sources
  • Resurrect Pages : Resurrect dead pages, by finding their ghosts
  • Selenium IDE : Record, edit and play Selenium tests
  • SQL Inject ME : An extension to test for SQL injection vulnerabilities
  • Tamper Data : View and modify HTTP/HTTPS headers etc. Track and time requests
  • URL Flipper : Quickly and easily increment and decrement numbers and strings in URLs
  • User Agent Switcher : Adds a menu and a toolbar button to switch the user agent of the browser
  • Vitzo WHOIS : The easiest and fastest WHOIS lookup add-on for Firefox
  • Wappalyzer : Weppalyzer is an add-on for Firefox that uncovers the technologies used on websites
  • Web Developer : Adds a menu and a toolbar with various web developer tools
  • XSS Me : An extension to test for Cross Site Scripting vulnerabilities

นอกจากนี้ก็จะเป็นพวก ช่วยเหลือทั้งหลายเช่น All-in-One Sidebar, Binewood, Tiny Menu, Ubuntu Firefox Modifications

นี่เป็นรูปร่างของbarด้านล่างของโปรแกรม เมื่อเปิดหน้าเวป

บอกหมดเลยว่า ip อะไร เวปserverอะไร แถมปุ่มต่างๆ คือเครื่องมือให้เราสามารถเล่นได้อีก

Verdict :
   Mantra เป็นโปรแกรมที่เจ๋งไปเลย  ถึงแม้ว่าจะดูเหมือนเป็นแค่การรวมเครื่องมือต่างๆเข้าไว้ด้วยกันที่เดียว และทำให้เป็นportableโดยใช้portable firefoxเป็นแกนหลัก  และcustomizedไว้ให้ใช้งานด้วยกันได้โดยสมบูรณ์  ก็สะดวกดีเลยเหมือนกัน

ถ้าคิดไปคิดมาแล้ว   มัน "Mantra" ก็คือ "Backtrack" สำหรับเวปไซต์นั่นเองแฮะ

เสียอย่างเดียว ยังไม่มี 64bit version....  ก็ยังรอ ร้อ รอ ต่อไป...

Cooking Blog

ช่วงนี้เริ่มสนใจการทำอาหารมากขึ้น
เลยเปิด blog ใหม่เลยละกันเรื่องทำอาหารอย่างเดียว
จะได้ไม่เกี่ยวข้องกับเรื่องของคอม

แล้วก็จะได้รวบรวมอะไรที่เคยทำไว้ในนี้ที่เดียว
เพราะบางทีอาจจะได้ปรินท์ออกมาทำเป็น cookbook ส่วนตัวก็ได้ :)

http://anidearcooking.blogspot.com/

12/14/2010

Gawker โดนแฮค

Gawker Media กลุ่มเวปไซต์ social media ที่มีเวปลูกๆรวมไปถึง Gawker, Gizmodo, Jalopnik, Jezebel, Kotaku, Lifehacker, Deadspin, io9, และ Fleshbot ได้ออกมาประกาศว่า เวปไซต์ของตัวเองได้ถูกกลุ่มผู้ไม่หวังดีล้วงข้อมูล username และ password ของสมาชิกไป
และขอให้สมาชิกเข้าไปเปลี่ยน รหัสผ่านเพื่อป้องกันตัวด้วย





ที่มาของเรื่องคือ หลังจากที่account twitterของกลุ่มGawkerได้ถุกเจาะและแก้ไขแล้ว ทีมงานเพิ่งมาทราบทีหลังว่า ผลกระทบมันรุนแรงกว่าแค่เพียงแค่twitterมาก เพราะมันได้ลามไปถึงการเสียข้อมูลของสมาชิกในเวปไปด้วย

จากข้อมูลที่ทางกลุ่มได้รับมา ทางกลุ่มคาดว่าเป็นฝีมือของกลุ่มที่ รวมตัวกันผ่านทางเวปบอร์ด 4chan และเป็นส่วนหนึ่งของกลุ่ม Anonymous ที่เพิ่งต่อสู้เพื่อWikileaksจากข่าวที่ผ่านๆมา แต่กลับไม่เป็นเช่นนั้น เพราะทีมงานได้รับemailมาโดยตรงบอกว่า




(แปล) พวกเราได้ยินว่าพวกคุณกำลังรายงานว่า gawker.com ถูกแฮคโดยกลุ่ม Anonymous และ Operation Payback ในสงครามดราม่าของwikileaksซึ่งกำลังเกิดขึ้นอยู่ตอนนี้ ถึงแม้ว่าเราจะรู้สึกเสียใจกับสถานการณ์ของWikileaksและสนับสนุนให้ทุกคนช่วยกันบริจาค แต่พวกเราไม่ได้มีส่วนเกี่ยวข้องกับ Operation Payback หรือสิ่งที่กลุ่มนั้นทำ พวกเราได้เจาะเข้าไปemailและฐานข้อมูล และ ข้อมูลรหัสผ่านจำนวนนึงได้ถูก unhashed ออกมาเป็น plaintext
เพื่อพิสูจน์ว่าเราพูดจริง, นี่คือตัวอย่างของข้อมูลในฐานข้อมูลนั้น:

หลังจากการตรวจสอบของทีมงาน พบว่า
นอกจากข้อมูลส่วนบุคคลที่โดนแฮคแล้ว บทสนทนาของสต๊าฟ, พาสเวิร์ดสต๊าฟที่ใช้ในวงnetworkและพาสเวิร์ดของสมาชิกที่ลงทะเบียนเพื่อโพสต์คอมเมนต์ ได้ถูกขโมยไปด้วย
ข้อมูลทั้งหมดนี้ถูกเอาไปโดยกลุ่มชื่อ Gnosis, ซึ่งภายหลังได้อัพโหลดข้อมูลพวกนี้ด้วย torrent ขนาด 500 MB ขึ้นไปที่ ThePirateBay ให้ดาวน์โหลดอย่างเปิดเผย ที่ http://thepiratebay.org/torrent/6034...1_300_000_rows... (ซึ่งโดนเอาออกไปแล้ว)



โดยช่องทางที่ทีมงานของ Gawker Media คาดว่า แฮกเกอร์ ใช้ช่องโหว่ของโปรแกรม Campfire ซึ่งเป็นโปรแกรมที่ทางทีมงานใช้ในการติดต่อสื่อสารงานเกี่ยวกับการจัดการเวปไซต์ รวมถึงหัวข้อข่าวที่จะเอามาเขียน ซึ่งทีมแฮกเกอร์นั้นได้สามารถเอาข้อมูลราวๆ 4GB ออกมาจาก log ของ Campfire ได้ ซึ่งในนี้รวมถึงข้อมูลusername,password การใช้ FTP ของ 7 บริษัทเกมส์ยักษ์ใหญ่ด้วย เช่น THQ, VALVE (e.g. Counter-Strike), Rockstar, Lucus Arts, Sony, 2K(e.g. Civilizaion)




ตอนนี้ นอกจากทาง Gawker ได้ประกาศผ่านทางหน้าเวปตัวเองแล้ว http://gawker.com/5712615/commenting-accounts-compromised-++-change-your-passwords
ทาง Gawker ได้ส่ง email แจ้งเตือนไปยังสมาชิกกว่า 200,000 คนแล้ว (ทั้งสมาชิกจากเวปGawker.comและเวปไซต์ลูกๆ)


และยังเปิดหน้า FAQ ไว้ที่ FAQ: Compromised Commenting Accounts on Gawker Media

ผู้ใช้ยังสามารถตรวจสอบได้ด้วยตัวเองว่า ข้อมูลของตนได้ถูกน้ำไปเผยแพร่หรือไม่ ด้วยการใช้เครื่องมือนี้ Gawker Check เพื่อเอา username, email ทำเป็น SHA-2,256bit,no salt และเปรียบเทียบกับข้อมูลที่รั่วออกมาในเวปได้เลย โดยไม่ต้องdownloadข้อมูลทั้งหมดแล้วมาเทียบเอง วิธีการโดยละเอียดทาง The easiest way to check if your email address is on the Gawker hacker list

ปล. ผู้ที่ใช้ Facebook ในการ Authenticate รอด! แต่ก็อย่าเพิ่งวางใจ ต้องรีบไปปลด connection ไปที่เวปเหล่านั้นทันที

ที่มา:



Update:
  กลุ่ม Gnosis ได้พยายามอัพโหลดtorrent เดิมขึ้น ThePirateBay อีกครั้งแล้ว

เวปไซต์ของ Anonymous เข้าไม่ได้... หรือว่าถูกจับไปแล้ว??

เมื่อพูดถึงสงครามออนไลน์แล้ว แค่เพียงข้อผิดพลาดเล็กๆน้อยๆ ก็ก่อให้เกิดความเสียหายมหาศาลได้ บทเรียนนี้ทำให้ชายที่ชื่อ Alex Tapanaris ได้เรียนรู้ด้วยตัวเองจริง เพราะเหตุจากที่ว่า ชื่อของเขาได้ถูกพบในmetadataของเอกสารPDF ที่ทางกลุ่มAnonymous ได้ออกมาให้กับสื่อมวลชน เพื่อบรรยายถึง Operation Payback ที่พวกเขากำลังทำอยู่เพื่อโจมตีเวปไซต์ชื่อดังต่างๆเช่น VISA, Mastercard, Paypal, Amazon ในโทษฐานที่ทำให้ Wikileaks ต้องปิดตัวลง

หลังจากที่เอกสารPDFฉบับนี้ได้ถูกเอาขึ้นในอินเตอร์เน็ต (ดูได้ที่ 
http://dump.no/files/467072ba2a42/AN...ss_Release.pdf ) ในวันที่ 10 ธันวาคม หลายๆเวปไซต์ก็เริ่มโพสต์กันว่า มีชื่อของ Alex Tapanaris อยู่ในข้อมูลmetadataของPDFนั้น ข้อผิดพลาดที่ไม่น่าเชื่อว่าจะเจอกับคนที่ยุ่งเกี่ยวกับเรื่องhackerแบบนี้ 

แต่ไม่ว่า Alex Tapanaris จะเป็นผู้ที่ทำหน้าที่เป็นโฆษกให้กับทาง Anonymous หรือไม่ ที่แน่ๆคือ ในวันจันทร์ที่ 13 ธันวาฯ เวปไซต์ต่างๆของ Anonymous ได้หยุดการให้บริการ(anonops.net,anonops.info,...) และมีข่าวที่ได้มาจากเวปไซต์ Pastebin.com ที่กลุ่มAnonymousชอบโพสต์ข้อความลงไป ได้บอกว่า Alex Tapanapis ได้ถูกจับกุมตัวเรียบร้อยแล้ว



ที่มา:
http://www.opentopic.com/FrontPage/news/1059


12/10/2010

Zeitgeist 2010: สรุปรอบปี 2010 สำหรับประเทศไทย

จาก ที่โพสต์ไปคราวก่อน http://blog.anidear.com/2010/12/googles-zeitgeist-2010.html
มันเป็น หน้า international
คราวนี้ลองมาดูหน้าไทยๆ กันบ้าง  จาก http://www.google.com/intl/en/press/zeitgeist2010/regions/th.html



เล็กไป แล้วก็ส่วนใหญ่ก็ไร้สาระ   เอาสรุปเลยดีกว่า

  • คำค้นหายอดนิยมของไทย สิบอันดับแรก!!!
    • เพลง, เกมส์, หนัง, facebook, hi5, งาน, ฟัง เพลง, เกม, 4shared, youtube
สุดยอดไปเลย คนไทยใช้เน็ตส่วนใหญ่เพื่อ entertainment ทั้งนั้น
  • "เพลงลูกเทวดา"  ติดอันดับข้อความค้นหาสูงสุด  เพลงอะไรอ่ะไม่เคยรู้จัก
  • "มาร์ค v11"  ติดอันดับคนที่ถูกค้นหามากที่สุด
    • รองลงมาเป็น Larissa Riquelme  : ที่เอานมหนีบโทรศัพท์ใช่มั๊ย
    • Justin Bieber : หนุ่มน้อยร้องเพลงเพราะ ดังมาถึงไทยเลย
    • ธัญญ่า :  คนคงsearchหาคลิปเสียงแน่ๆ
    • แอนนี่ : นี่ก็เรื่องใหญ่ประจำปีเหมือนกัน
    • ฟิลม์ :  ติดอันดับเหมือนกัน แต่โดนค้นหาน้อยกว่าแอนนี่เยอะมากๆ
    • ริท,กัน : นี่ก็ดังติดอันดับเหมือนกัน
น่าแปลก นาธาน ไม่ติดอันดับแฮะ
  • รวมข่าวเด็ดประจำปี
    • "สถานการณ์ เสื้อแดง"
    • "ข่าวน้ำท่วม"
    • "จ่าเพียร"
    • "ยุบพรรค ประชาธิปัตย์"
    • "เสธแดง"
    • "อริสมันต์หนี"
    • "แอร์พอร์ตลิงค์"
    • "พงษ์พัฒน์"
    • "เซ็นทรัลเวิลด์ถล่ม"
    • "ปาเกียว"  :  ???
อันอื่นก็ไม่เห็นมีอะไรน่าสนใจเท่าไหร่  จบแค่นี้ละกัน


12/09/2010

Google's Zeitgeist 2010

From http://googleblog.blogspot.com/2010/12/zeitgeist-2010-how-world-searched.html

สรุปข่าวรอบโลก ประจำปี 2010
Google จะใช้วิธีวิเคราะห์ คำที่ผู้ใช้ใช้ค้นหาในGoogle
โดยเก็บข้อมูลทั้ง

  • keyword ที่ใช้ค้นหา
  • Location ของผู้ใช้
  • Time 
น่าดีใจมั๊ยเนี่ย  ข่าวจากประเทศไทยได้ช่วงเวลาหลายวินาทีอยู่ในวีดีโอนี้ด้วย  เฮ้อ...



12/07/2010

Research Writing Concept

A note to myself (after talking with Susan)

"Technical Writing is more like advertisements
It focuses on telling how it is great first, and why it is great."

"The process of explaining the story is the opposite of novels, or movies, or story telling.
Technical writings tell the end first, then explain why it ends the way it ends"

Comparing to "Lord of the Ring"
  Movie will start telling from who is Frodo, and building up why he needs to destroy the ring, facing many enemies while walking through the forest,... blah blah ... and finally showing he actually did it.

 On the other hand, technical writing is starting by telling "Frodo actually did destroy the ring, Yeah!!".... why he did that,.. who is he,...any alternative?... oh!  that's why he destroyed it.... the end.

12/06/2010

Import StackOverflow DataDump into My Own Database

I'm about to duplicate StackOverflow data for researching purpose.

My database is MySQL v.5+ (I really forget the version number)
The problem is ..  the data dump from StackOverflow comes in XML format,
which I couldn't find any tool to help me import those into MySQL database.

data dump from http://blog.stackoverflow.com/category/cc-wiki-dump/

The format is like this:
<?xml version="1.0" encoding="utf-8"?>
<badges>
  <row Id="82946" UserId="3718" Name="Teacher" Date="2008-09-15T08:55:03.923" />
  <row Id="82947" UserId="994" Name="Teacher" Date="2008-09-15T08:55:03.957" />
  ...
</badges>

So, I think I have no choice but to implement an xml importer myself.

Specifications of my problem:

  • Importing all dumped data from StackOverflow into my MySQL database
  • data dump can be downloaded from http://blog.stackoverflow.com/category/cc-wiki-dump/
  • data dump comes in format of several XML files in one folder
    • each XML file represents one table
      • each row node in XML represents one row of data
      • each attribute of each node represents one column
    • XML file size ranges from 85MB to 5.4 GB (badges.xml , posthistory.xml)
  • MySQL is running on a remote server
  • Need to be Java language implementation, for others to read

My 4 concerns are:
  • Schema of tables are currently unknown
    • although I can guess the configurations of each table's fields from looking at each XML, but it does not specify how large the field is.
  • XML files are large, using XML parser like XPATH would consume too much memory and processing time.
  • inserting large data into MySQL database would be very slow
  • supporting for new data. If there's a new data dump coming in next month, it must support to import new data into the database.
Solution:
  • For the first problem, I found a SQL script for creating StackOverflow's tables for MSSQL here http://code.google.com/p/stack-exchange-data-explorer/source/browse/Data/stackoverflow.sql. It's an opensource program to explorer stackoverflow data using ODATA format. On today (12/6/10), the file is gone. However, I have seen it and translated the script from MSSQL format into MySQL format, seen below.
  • Although, Large XML files couldn't be parsed efficiently with DOM,JDOM,XPATH, they could be parsed with SAX and Stax easily. Here I use Stax because it's more easily to use.
  • Slow inserting to database, this can be solved by batch processing. I have a configuration parameter in the config.properties file to set how many rows per one batch insert and commit
    • Using 1000 rows/batch, the program managed to use 300kB/s for uploading to database, which took about 8 hours for all files to finish (I excludes PostHistory.xml from the process)
    • Another solution is to use LOAD DATA INFILE ... , but it requires me to upload data into a file format that is readable by MySQL. It'd raise another concern on how to make the file, especially there are fields containing plain+HTML text.
  • I found an SQL command called "REPLACE". It is proprietary for MySQL. What it does is it will delete the row(only if the row is duplicated), and then insert new one. This command is opposite of "INSERT IGNORE" which ignores the new insert if it's duplicated. I think I should keep new data instead of old data, so I picked "REPLACE" command.

SQL script for creating database and tables
CREATE DATABASE IF NOT EXISTS StackOverflow

USE StackOverflow

CREATE TABLE IF NOT EXISTS VoteTypes(
 Id int NOT NULL,
 Name varchar(40) NULL,
 PRIMARY KEY (Id)
);

CREATE TABLE IF NOT EXISTS Votes(
 Id int NOT NULL,
 PostId int NULL,
 VoteTypeId int NULL,
 CreationDate datetime NULL,
 CONSTRAINT PK_Votes PRIMARY KEY (id)
);

CREATE TABLE IF NOT EXISTS Users(
 Id int NOT NULL,
 Reputation int NULL,
 EmailHash varchar(40) NULL,
 CreationDate datetime NULL,
 DisplayName varchar(40) NULL,
 LastAccessDate datetime NULL,
 WebsiteUrl varchar(200) NULL,
 Location varchar(100) NULL,
 Age int NULL,
 AboutMe LONGTEXT NULL,
 Views int NULL,
 UpVotes int NULL,
 DownVotes int NULL,
 CONSTRAINT PK_Users PRIMARY KEY (Id)
);

CREATE TABLE IF NOT EXISTS Tags(
 Id int NOT NULL,
 TagName varchar(255) NULL,
 PRIMARY KEY(Id)
);

CREATE TABLE PostTags(
 PostId int NULL,
 TagId int NULL
);

CREATE TABLE IF NOT EXISTS Posts(
 Id int NOT NULL,
 PostTypeId int NULL,
 AcceptedAnswerId int NULL,
 CreationDate datetime NULL,
 Score int NULL,
 ViewCount int NULL,
 Body LONGTEXT NULL,
 OwnerUserId int NULL,
 OwnerDisplayName nvarchar(40) NULL,
 LastEditorUserId int NULL,
 LastEditDate datetime NULL,
 LastActivityDate datetime NULL,
 Title nvarchar(250) NULL,
 Tags nvarchar(150) NULL,
 AnswerCount int NULL,
 CommentCount int NULL,
 FavouriteCount int NULL,
 ClosedDate datetime NULL,
 ParentId int NULL,
 CommunityOwnedDate datetime NULL,
 CONSTRAINT PK_Posts PRIMARY KEY (id)
);

CREATE TABLE IF NOT EXISTS Comments(
 Id int NOT NULL,
 PostId int NULL,
 Score int NULL,
 Text LONGTEXT NULL,
 CreationDate datetime NULL,
 UserId int NULL,
 CONSTRAINT PK_Comments PRIMARY KEY (Id)
);

CREATE TABLE IF NOT EXISTS Badges(
 Id int NOT NULL,
 UserId int NULL,
 Name varchar(50) NULL,
 Date datetime NULL,
 CONSTRAINT PK_Badges PRIMARY KEY (Id)
);



This is the code "XMLDumpImporter"
/**
* This is a tool for importing StackOverflow data dump into MySQL database.
* @author ptantiku
*/
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.util.Properties;

import javax.xml.stream.XMLInputFactory;
import javax.xml.stream.XMLStreamConstants;
import javax.xml.stream.XMLStreamException;
import javax.xml.stream.XMLStreamReader;

public class XMLDumpImporter {

 Properties properties = null;
 String serveraddress;
 String port;
 String username;
 String password;
 String databasename;
 private int rowspercommit;
 String filePath;

 Connection connection;
 

 /**
  * Main Program 
  * @param args
  * @throws IOException
  */
 public static void main(String[] args) throws IOException {
  XMLDumpImporter xmlImporter = new XMLDumpImporter(
    "/media/DeerDisk2/Download/Stack Overflow Data Dump - Nov 2010/Content/112010 Stack Overflow");
  xmlImporter.importXMLFolder();
  xmlImporter.closeDB();
 }

 public XMLDumpImporter(String path) {
  loadConfig();
  connectDB();
  filePath = path;
 }

 private void loadConfig() {
  // create an instance of properties class
  properties = new Properties();

  // try retrieve data from file
  try {
   properties.load(new FileInputStream("config.properties"));
   serveraddress = properties.getProperty("serveraddress");
   port = properties.getProperty("port");
   username = properties.getProperty("username");
   password = properties.getProperty("password");
   databasename = properties.getProperty("databasename");
   rowspercommit = Integer.parseInt(properties.getProperty("rowspercommit"));
  } // catch exception in case properties file does not exist
  catch (IOException e) {
   e.printStackTrace();
  }
 }

 private void connectDB() {
  // connect to MySQL
  connection = null;
  try {
   // Load the JDBC driver
   String driverName = "org.gjt.mm.mysql.Driver"; // MySQL MM JDBC
               // driver
   Class.forName(driverName);

   // Create a connection to the database
   String url = "jdbc:mysql://" + serveraddress +":" + port + "/" + databasename; 
   connection = DriverManager.getConnection(url, username, password);
   connection.setAutoCommit(false);  //for batch insert
  } catch (ClassNotFoundException e) {
   // Could not find the database driver
   e.printStackTrace();
  } catch (SQLException e) {
   // Could not connect to the database
   e.printStackTrace();
  }
 }

 public void importXMLFolder() throws IOException {
  File path = new File(filePath);
  if (path == null || !path.isDirectory()) {
   throw new IOException("Path is wrong");
  }
  String fileList = properties.getProperty("filelist");
  String[] fileListArray = fileList.split(",");

  String tableName = properties.getProperty("tablename");
  String[] tableNameArray = tableName.split(",");

  for(int i=0;i<fileListArray.length;i++){
  //for (int i = 0; i < 1; i++) {
   String filename = filePath + File.separatorChar + fileListArray[i];
   String table = tableNameArray[i];
   importXMLFile(filename, table);
  }
 }

 public void importXMLFile(String filename, String tablename)
   throws IOException {
  System.out.println("Processing file: " + filename);

  String fields = properties.getProperty(tablename+"_fields");
  String[] fieldsArray = fields.split(",");
  
  
  
  try {
   FileInputStream fin = new FileInputStream(new File(filename));
   XMLInputFactory factory = XMLInputFactory.newInstance();
   XMLStreamReader r = factory.createXMLStreamReader(fin);
   int attributeCount = 0;
   int rowCount = 0;

   //connection part
   if(connection==null||connection.isClosed())
    connectDB();
   //REPLACE is non-standard SQL from MySQL, it's counter part of INSERT IGNORE
   String sql = "REPLACE INTO "+tablename+" ("+fields+") VALUES ("+fields.replaceAll("[^,]+", "?")+")";
   System.out.println("SQL: "+sql);
   PreparedStatement pstmt = connection.prepareStatement(sql);
   
   // start parsing
   int event = r.getEventType();
   while (true) {
    // for each wanted element 
    if (event == XMLStreamConstants.START_ELEMENT
      && r.getName().toString().equalsIgnoreCase("row")) {
     System.out.println("Table : "+tablename+" / Row : "+rowCount );
     if (attributeCount == 0)
      attributeCount = r.getAttributeCount();

     /*for (int a = 0; a < attributeCount; a++) {
      System.out.print("\t{" + r.getAttributeName(a) + ":"
        + r.getAttributeValue(a) + "}");
     }
     System.out.println();
     */
     
     //put each parameter to SQL
     int f=1;
     for (String field : fieldsArray){
      pstmt.setString(f++,r.getAttributeValue("", field));
     }
     pstmt.addBatch();
     rowCount++;
     
     if(rowCount%rowspercommit==0){
      System.out.println("Importing at row "+rowCount+" ... ");
      pstmt.executeBatch();
      connection.commit();
     }
    } // end for each row.

    // proceeding to next element
    if (!r.hasNext())
     break;
    else
     event = r.next();
   }

   System.out.println("Importing all rows into database (it might take time) ... ");
   pstmt.executeBatch();
   connection.commit();
   pstmt.close();
   r.close();
   fin.close();
   System.out.println("Importing "+filename+" is done");
  } catch (XMLStreamException e) {
   e.printStackTrace();
  } catch (SQLException e) {
   e.printStackTrace();
  }
 }
 
 public void closeDB(){
  try {
   if(connection!=null&&!connection.isClosed())
    connection.close();
  } catch (SQLException e) {
   e.printStackTrace();
  }
 }
}

This code needs config.properties file to supply necessary data to them, such as database configurations, StackOverflow table configurations.

This is the content of "config.properties" file (db config is masked):
# This is configuration file for XMLDumpImporter
serveraddress = XXX.XXX.XXX.XXX
port = 3306
username = XXXXX
password = XXXXX
databasename = StackOverflow

#number of rows inserted before each commit
rowspercommit = 1000

#file list for checking and processing in order
filelist = badges.xml,posts.xml,votes.xml,comments.xml,users.xml

#table name, sequentially according to filelist
tablename = badges,posts,votes,comments,users

#database fields: key = tablename_fields
badges_fields = Id,UserId,Name,Date
posts_fields = Id,PostTypeId,AcceptedAnswerId,CreationDate,Score,ViewCount,Body,OwnerUserId,OwnerDisplayName,LastEditorUserId,LastEditDate,LastActivityDate,Title,Tags,AnswerCount,CommentCount,FavouriteCount,ClosedDate,ParentId,CommunityOwnedDate
votes_fields = Id,PostId,VoteTypeId,CreationDate
comments_fields = Id,PostId,Score,Text,CreationDate,UserId
users_fields = Id,Reputation,EmailHash,CreationDate,DisplayName,LastAccessDate,WebsiteUrl,Location,Age,AboutMe,Views,UpVotes,DownVotes


In this work, I ignore the table "posthistory", since I have no use for it yet.

Other related info:
Odata from http://odata.stackexchange.com/stackoverflow/query/new
Odata explanation :: http://sqlserverpedia.com/wiki/Understanding_the_StackOverflow_Database_Schema
Doc: www.odata.org/developers/odata-sdk
Data dump @ http://blog.stackoverflow.com/category/cc-wiki-dump/
StackOverflow Schema: http://code.google.com/p/stack-exchange-data-explorer/source/browse/Data/stackoverflow.sql

12/02/2010

ภาษาไทย Chrome บน Ubuntu

หลังจากประสบปัญหามาอยู่นาน กับภาษาไทยบน google chrome
ที่สระเลื่อนกันตลอดเวลา  จนรำคาญหนีไปใช้ Firefox อยู่ร่ำไป (เพราะภาษาไทยมันดีกว่า)
แต่พอจะตัดขาดกับ Chrome ก็ตัดไม่ได้ซักที  เพราะชอบความเรียบง่ายกับความโล่งของหน้าจอมากกว่า

ปัญหาที่เจอสระเลื่อนเนี่ย หนักขนาดที่ว่า  พอช่วงที่ละครเรื่องวนิดาออกมาเนี่ย
ก็คุยกับเพื่อนในfacebook แล้วก็เช็คข่าวในเน็ต
ไม่ว่าจะมองไปทางไหน  ก็เห็นว่าเรื่อง "วินดา" เนี่ย ฮิตติดชาร์ตทั่วบ้านทั่วเมือง
ไอ้เราก็เข้าใจว่ามันชื่อเรื่องว่า "วินดา"   พอได้ไปคุยกะใครล่ะงงกันไปข้างนึงเลย

จนวันนี้เพิ่งได้มาเจอกับวิธีการใช้ Chrome ให้มันแสดงภาษาไทยได้
อ้างอิงจากเวปนี้นะ http://ubuntuclub.com/node/2332
เขาบอกว่า developer คนไทยน่ะ(@nattster , @lewcpe and @aborigine) แก้ไว้ให้แล้ว
แต่ไอ้ต้นสังกัด chrome น่ะ ดันไม่เอาขึ้นต้นน้ำให้ มันก็เลยไม่มีให้ใช้กัน ฝรั่งไม่แคร์ ... เฮ้อ...

เขาเลยจัดการ modify chromium ซึ่งเป็น opensourceของ chrome แล้วจัดการสมัครlaunchpad ของ ubuntu เพื่อให้ผู้ที่สนใจเข้าไปดาวน์โหลดมาใช้ได้เลยทันที

ส่วนวิธีinstall (โดยเราเป็นผู้ใช้ก็ลงแบบstableละกันเนอะ) ก็มีดังนี้

sudo apt-add-repository ppa:thai/chromium-thai-stable
sudo apt-get update
sudo apt-get install chromium-browser

เสร็จแล้ว ก็จะได้เมนูที่ชื่อ Chromium หน้าตาเหมือนโครมเด๊ะๆ อยู่ในเมนู Applications-->Internet

แล้วพอมาทดลองเปรียบเทียบการแสดงผลกัน

แน่นอน หน้าตาเหมือนกันเด๊ะๆ  และผลลัพธ์นี้ผมไม่ได้ fake แต่ประการใด ไม่เชื่อลองกดที่รูปเข้าไปดูรูปใหญ่ได้

URLเหมือนกัน ผลลัพธ์ก็เหมือนกันเด๊ะ  แต่อันนึงเป็นละครชื่อ "วินดา" กับอีกอันเป็นละครที่ชื่อ "วนิดา"

ฮ่าๆๆ  โดนกูเกิ้ลหลอกอีกแล้วววววว