ชุมชนคนรักภาษาเบสิค - Visual Basic Community

 ลืมรหัสผ่าน
 ลงทะเบียน
ค้นหา
ดู: 784|ตอบกลับ: 0

[VB.NET] การสุ่มหมายเลขบัตรประชาชน 13 หลัก และตรวจสอบความถูกต้องของรหัสหลักที่ 13

[คัดลอกลิงก์]

252

กระทู้

370

โพสต์

3088

เครดิต

ผู้ดูแลระบบ

Rank: 9Rank: 9Rank: 9

เครดิต
3088



แอดมินแจกโค้ดนี้เอาไว้เมื่อราวๆปี 2549 เอาไว้สุ่มหมายเลขบัตรประชาชนเอาเพื่อไปเล่นเกมส์ 5555+ ... เรามาดูวิธีการคิดกันครับ ...


วิธีคิดในการสุ่มเลขจำนวน 12 หลัก แล้วหา Check Digit หลักที่ 13 ... เช่น 7736830472815 เมื่อ 5 คือหลักที่ 13 หรือ Check Digit ...
หาผลรวมตั้งแต่หลักที่ 1 ไปจนถึงหลักที่ 12 (นับจากซ้ายไปขวา)
โดยให้หลักที่ 1 คูณด้วยน้ำหนักประจำหลัก = 13 ... (7 x 13)
โดยให้หลักที่ 2 คูณด้วยน้ำหนักประจำหลัก = 12 ... (7 x 12)
โดยให้หลักที่ 3 คูณด้วยน้ำหนักประจำหลัก = 11 ... (3 x 11)
โดยให้หลักที่ (เพิ่มขึ้น 1) คูณด้วยน้ำหนักประจำหลัก = (ลดลง 1)
โดยให้หลักที่ 12 คูณด้วยน้ำหนักประจำหลัก = 2 ... (1 x 2)

จากนั้นนำผลการคูณของแต่ละหลักมารวมกันเข้าไป

หลักแต่ละหลัก คือ Val(Mid$(txtIDcard.Text, Count, 1))
น้ำหนักของแต่ละหลัก คือ (14 - Count) เมื่อ Count เริ่มต้นจาก 1 ไปสิ้นสุดที่ 12 ดังนั้นค่านี้ (14 - Count) จึงเริ่มต้นค่าจาก 13, 12, 11, ..., สิ้นสุดที่ 2 ครับผม
จะได้โค้ดดังนี้ ...
  1. Sum = 0
  2. For Count = 1 To 12
  3.     Sum = Sum + Val(Mid$(txtIDcard.Text, Count, 1)) * (14 - Count)
  4. Next
คัดลอกไปที่คลิปบอร์ด

ลักษณะของการนำตัวแปร Sum มาเวียนใช้งาน สำหรับมือใหม่หัดขับในการพัฒนาโปรแกรม พยายามศึกษาการทำงานมันให้ดีน่ะครับ เพราะคุณต้องนำมันมาใช้งานตลอดทั้งชีวิตของการเขียนโปรแกรมของคุณแน่ๆ

นำผลรวมที่ได้มา Mod (การหารเอาเศษ) ด้วย 11 นั่นคือค่าที่เราจะได้ก็คือ 0, 1, 2, .. , 10 (Sum Mod 11)
เพิ่มเติม: เรา Mod ด้วยอะไร ก็จะได้ค่าสูงสุด (ที่เป็นไปได้) ของตัว Mod ลบด้วย 1 เสมอ (ในที่นี้คือ 11 - 1 = 10)
เพิ่มเติม: เรามักจะนำตัวเลขจำนวนเต็มมา Mod ด้วย 2 เพื่อตรวจสอบว่าเลขจำนวนเต็มนั้นมันเป็นเลขคู่ หรือ เลขคี่ หาก Mod แล้วได้ 0 นั่นคือ เป็นเลขคู่ หาก Mod แล้วผลลัพธ์เป็น 1 แสดงว่าเป็นเลขคี่

เอ้ามาว่ากันต่อไป ...
จากนั้นให้ลบออกด้วย 11 ก็จะทำให้ได้ค่าตั้งแต่ 1, 2, 3, ... , 11 (11 - (Sum Mod 11))
แล้วให้เลือกตัวขวามือสุดมาหนึ่งตัว ด้วยคำสั่ง Right$ --> Right$(Str(11 - (Sum Mod 11)), 1)
สุดท้ายก็ให้นำมาเปรียบเทียบกับหลักที่ 13 ของหมายเลขบัตรประชาชน ว่ามันตรงกันหรือไม่ ?
หากตรงกันก็แสดงว่า เป็นบัตรแท้, หากไม่ตรงกัน ก็คือ บัตรเก๊ เท่านี้เองครับพี่น้อง

มาดูโค้ดฉบับเต็มกันเถอะ ...
  1. Public Class frmCheckIDCard

  2.     Private Sub btnRandom_Click(sender As System.Object, e As System.EventArgs) Handles btnRandom.Click
  3.         txtIDCard.Clear()
  4.         '/ สุ่มหาตัวเลขมาทั้งหมด 12 หลัก โดยที่หลักแรกต้องไม่ใช่ 0 และ 9 ด้วย
  5.         '/ เรียกไปยังฟังค์ชั่น RandomNumber โดยไม่มีการส่งค่าใดๆไป แต่จะต้องรับค่าที่ได้กลับมา
  6.         txtIDCard.Text = RandomNumber()

  7.         ' หลักคิดสำหรับ 12 หลักแรก
  8.         ' เริ่มต้นคำนวณหาค่าผลรวมตัวเลขทั้ง 12 หลักแรก ดังนี้
  9.         ' หาผลรวมตั้งแต่หลักที่ 1 ไปจนถึงหลักที่ 12 (นับจากซ้ายไปขวา)
  10.         ' โดยให้หลักที่ 1 คูณด้วยน้ำหนักประจำหลัก = 13
  11.         ' โดยให้หลักที่ 2 คูณด้วยน้ำหนักประจำหลัก = 12
  12.         ' โดยให้หลักที่ 3 คูณด้วยน้ำหนักประจำหลัก = 11
  13.         ' โดยให้หลักที่ .. คูณด้วยน้ำหนักประจำหลัก = ..
  14.         ' โดยให้หลักที่ 12 คูณด้วยน้ำหนักประจำหลัก = 2
  15.         ' จากนั้นนำผลการคูณของแต่ละหลักมารวมกันเข้าไป

  16.         ' หลักแต่ละหลัก คือ Val(Mid$(txtIDcard.Text, Count, 1))
  17.         ' น้ำหนักของแต่ละหลัก คือ (14 - Count) เมื่อ Count เริ่มต้นจาก 1 ไปสิ้นสุดที่ 12
  18.         ' ดังนั้นค่านี้ (14 - Count) จึงเริ่มต้นค่าจาก 13, 12, 11, ..., สิ้นสุดที่ 2 ครับผม
  19.         Dim Sum As Integer = 0
  20.         For Count As Byte = 1 To 12
  21.             Sum = Sum + Val(Mid$(txtIDCard.Text, Count, 1)) * (14 - Count)
  22.         Next

  23.         ' / --------------------------------------------------------------------
  24.         ' ขั้นตอนนี้ คือ การหาค่า Check Digit (หลักที่ 13) หรือ หลักตรวจสอบความถูกต้อง
  25.         ' นำผลรวมที่ได้ (Sum) มา Mod (การหารเอาเศษ) ด้วย 11 นั่นคือค่าที่เราจะได้ก็คือ 0, 1, 2, .. , 10 (Sum Mod 11)
  26.         ' จากนั้นให้ลบออกด้วย 11 ก็จะทำให้ได้ค่าตั้งแต่ 1, 2, 3, ... , 11 (11 - (Sum Mod 11))
  27.         ' แล้วให้เลือกตัวขวามือสุดมาหนึ่งตัว ด้วยคำสั่ง Right$ --> Right$(Str(11 - (Sum Mod 11)), 1)
  28.         ' ค่าสุดท้ายนี้ก็คือ หลักที่ 13 หรือ หลักตรวจสอบความถูกต้อง (Check Digit) นั่นเอง
  29.         '
  30.         Dim CheckDigit As String = Microsoft.VisualBasic.Right(Str(11 - (Sum Mod 11)), 1)
  31.         txtIDCard.Text = txtIDCard.Text + CheckDigit
  32.     End Sub

  33.     ' / --------------------------------------------------------------------
  34.     ' ฟังค์ชั่นที่ใช้ในการสุ่มตัวเลขจำนวน 12 หลัก ไม่มีการรับค่า แต่จะต้องส่งค่าคืนกลับไป (Return)
  35.     ' ดังนั้นเราต้องใช้เป็นแบบฟังค์ชั่น (Function)  จะใช้ Sub Program ไม่ได้
  36.     ' / --------------------------------------------------------------------
  37.     Function RandomNumber() As String
  38.         RandomNumber = String.Empty

  39.         ' เริ่มต้นในการสุ่มตัวเลข
  40.         Randomize()
  41.         Dim rndID As New Random
  42.         '/ เพื่อบ่งบอกว่าหลักแรกหาค่าได้สำเร็จแล้วหรือไม่
  43.         Dim blnFlag As Boolean = False
  44.         Dim i As Byte = 1
  45.         ' สุ่มเลขจำนวน 12 หลัก โดยที่หลักแรกต้องไม่ใช่ 0 และ 9
  46.         ' i เริ่มต้นจาก 1
  47.         While i <> 12
  48.             ' Not False หรือ ไม่จริง ก็คือ เท็จ (หรือเขียน blnFlag = False) ... แสดงว่าตอนนี้เรากำลังจะหาตัวเลขหลักแรกอยู่
  49.             If Not blnFlag Then
  50.                 ' สุ่มตัวเลขหลักแรก ต้องไม่ให้มีค่าเป็น 0 และ 9 ... นี่คือการทำซ้ำ หรือ Repetitive
  51.                 Do
  52.                     RandomNumber = rndID.Next(0, 9)

  53.                     ' ทำจนกว่าหลักแรกต้องไม่เท่ากับ 0 และ 9 (เงื่อนไขต้องใช้ AND)
  54.                     ' เช่น เมื่อ RandomNumber มีค่า = 1
  55.                     ' ทำให้ได้เงื่อนไข 1 <> 0 และ 1 <> 9 (True AND True = True) ... เงื่อนไขเป็น "จริง" ให้ออกจาก Loop
  56.                     ' หรือ เมื่อ RandomNumber มีค่า = 9
  57.                     ' ทำให้ได้เงื่อนไข 9 <> 0 และ 9 <> 9 (True AND False = False) ... เงื่อนไขเป็น "เท็จ" ให้วน Loop ต่อไป
  58.                 Loop Until RandomNumber <> 0 And RandomNumber <> 9

  59.                 ' หรือ ใช้เงื่อนไข Until แต่กลับกันด้วย Not ...
  60.                 'Loop Until Not RandomNumber = 0 And Not RandomNumber = 9

  61.                 ' หรือใช้ While แต่เงื่อนไขต้องกลับกันกับแบบ Until และต้องใช้ OR แทนที่
  62.                 ' เช่น เมื่อ RandomNumber มีค่า = 1
  63.                 ' ทำให้ได้เงื่อนไข 1 = 0 หรือ 1 = 9 (False OR False = False) ... เงื่อนไขเป็น "เท็จ" ให้ออกจาก Loop
  64.                 ' หรือ เมื่อ RandomNumber มีค่า = 9
  65.                 ' ทำให้ได้เงื่อนไข 9 = 0 หรือ 9 = 9 (False OR True = True) ... เงื่อนไขเป็น "จริง" ให้วน Loop ต่อไป
  66.                 'Loop While RandomNumber = 0 Or RandomNumber = 9

  67.                 ' แจ้งว่าหลักแรกหาตัวเลขที่ไม่ใช่ 0 หรือ 9 เสร็จสมบูรณ์แล้ว หลักต่อไปจะได้ไม่ต้องเข้าไป Do Loop อีก
  68.                 blnFlag = True
  69.             End If

  70.             ' หาค่าจำนวนหลักที่เหลือ แล้วส่งค่าคืนกลับของฟังค์ชั่นไปได้เลย
  71.             RandomNumber = RandomNumber & rndID.Next(0, 9)
  72.             '// Increment Counter
  73.             i += 1
  74.         End While
  75.     End Function

  76.     ' / --------------------------------------------------------------------
  77.     ' / ตรวจสอบหมายเลขบัตรประชาชน
  78.     Private Sub btnCheck_Click(sender As System.Object, e As System.EventArgs) Handles btnCheck.Click
  79.         '/ ไม่มีการป้อนข้อมูล ก็ให้ออกจากโปรแกรมย่อยไป
  80.         If txtIDCard.Text = "" Or txtIDCard.Text.Trim.Length = 0 Then Exit Sub
  81.         ' ความยาวต้องเท่ากับ 13 หลัก
  82.         If Len(txtIDCard.Text) < 13 Then
  83.             MsgBox("กรุณากรอกหมายเลขบัตรประชาชนให้ครบทั้ง 13 หลักด้วย.", vbOKOnly + vbExclamation, "รายงานความผิดพลาด")
  84.             Exit Sub
  85.         End If
  86.         ' หาผลรวมตั้งแต่หลักที่ 1 ไปจนถึงหลักที่ 12
  87.         Dim Sum As Integer = 0
  88.         For Count As Byte = 1 To 12
  89.             Sum = Sum + Val(Mid(txtIDCard.Text, Count, 1)) * (14 - Count)
  90.         Next
  91.         ' เปรียบเทียบค่าที่ได้กับหลักที่ 13
  92.         If Microsoft.VisualBasic.Right(txtIDCard.Text, 1) = Microsoft.VisualBasic.Right(Str(11 - (Sum Mod 11)), 1) Then
  93.             MessageBox.Show("หมายเลขบัตรประชาชน " & txtIDCard.Text & " ถูกต้อง.", "รายงานการตรวจสอบ", MessageBoxButtons.OK, MessageBoxIcon.Information)
  94.         Else
  95.             MessageBox.Show("หมายเลขบัตรประชาชน " & txtIDCard.Text & " ไม่ถูกต้อง.", "รายงานการตรวจสอบ", MessageBoxButtons.OK, MessageBoxIcon.Exclamation)
  96.         End If
  97.     End Sub

  98.     Private Sub frmCheckIDCard_Load(sender As System.Object, e As System.EventArgs) Handles MyBase.Load
  99.         txtIDCard.Focus()
  100.     End Sub

  101.     Private Sub txtIDCard_KeyPress(sender As Object, e As System.Windows.Forms.KeyPressEventArgs) Handles txtIDCard.KeyPress
  102.         If Asc(e.KeyChar) = 13 Then
  103.             e.Handled = True
  104.             btnCheck_Click(sender, e)
  105.         Else
  106.             e.Handled = CheckDigitOnly(Asc(e.KeyChar))
  107.         End If
  108.     End Sub

  109.     ' / ฟังค์ชั่นในการป้อนเฉพาะค่าตัวเลขได้เท่านั้น
  110.     Function CheckDigitOnly(ByVal index As Integer) As Boolean
  111.         Select Case index
  112.             Case 48 To 57 ' เลข 0 - 9
  113.                 CheckDigitOnly = False
  114.             Case 8, 13 ' Backspace = 8, Enter = 13
  115.                 CheckDigitOnly = False
  116.             Case Else
  117.                 CheckDigitOnly = True
  118.         End Select
  119.     End Function

  120. End Class
คัดลอกไปที่คลิปบอร์ด


ดาวน์โหลดโค้ดต้นฉบับ VB.NET (2010) ได้จากที่นี่ ...

ขออภัย! โพสต์นี้มีไฟล์แนบหรือรูปภาพที่ไม่ได้รับอนุญาตให้คุณเข้าถึง

คุณจำเป็นต้อง ลงชื่อเข้าใช้ เพื่อดาวน์โหลดหรือดูไฟล์แนบนี้ คุณยังไม่มีบัญชีใช่ไหม? ลงทะเบียน

x
สิ่งที่ดีกว่าการให้ คือการให้แบบไม่มีที่สิ้นสุด
ขออภัย! คุณไม่ได้รับสิทธิ์ในการดำเนินการในส่วนนี้ กรุณาเลือกอย่างใดอย่างหนึ่ง ลงชื่อเข้าใช้ | ลงทะเบียน

รายละเอียดเครดิต

ข้อความล้วน|อุปกรณ์พกพา|ประวัติการแบน|G2GNet.com  

GMT+7, 2020-9-28 19:50 , Processed in 0.266192 second(s), 4 queries , File On.

Powered by Discuz! X3.3 R20170401, Rev.54

© 2001-2017 Comsenz Inc.

ตอบกระทู้ ขึ้นไปด้านบน ไปที่หน้ารายการกระทู้