|  | 
 
|  
 แอดมินแจกโค้ดนี้เอาไว้เมื่อราวๆปี 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 ครับผม
 จะได้โค้ดดังนี้ ...
 
 คัดลอกไปที่คลิปบอร์ดSum = 0
For Count = 1 To 12
    Sum = Sum + Val(Mid$(txtIDcard.Text, Count, 1)) * (14 - Count)
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 ของหมายเลขบัตรประชาชน ว่ามันตรงกันหรือไม่ ?
 หากตรงกันก็แสดงว่า เป็นบัตรแท้, หากไม่ตรงกัน ก็คือ บัตรเก๊ เท่านี้เองครับพี่น้อง
 
 มาดูโค้ดฉบับเต็มกันเถอะ ...
 
 คัดลอกไปที่คลิปบอร์ดPublic Class frmCheckIDCard
    Private Sub btnRandom_Click(sender As System.Object, e As System.EventArgs) Handles btnRandom.Click
        txtIDCard.Clear()
        '/ สุ่มหาตัวเลขมาทั้งหมด 12 หลัก โดยที่หลักแรกต้องไม่ใช่ 0 และ 9 ด้วย
        '/ เรียกไปยังฟังค์ชั่น RandomNumber โดยไม่มีการส่งค่าใดๆไป แต่จะต้องรับค่าที่ได้กลับมา
        txtIDCard.Text = RandomNumber()
        ' หลักคิดสำหรับ 12 หลักแรก
        ' เริ่มต้นคำนวณหาค่าผลรวมตัวเลขทั้ง 12 หลักแรก ดังนี้
        ' หาผลรวมตั้งแต่หลักที่ 1 ไปจนถึงหลักที่ 12 (นับจากซ้ายไปขวา)
        ' โดยให้หลักที่ 1 คูณด้วยน้ำหนักประจำหลัก = 13
        ' โดยให้หลักที่ 2 คูณด้วยน้ำหนักประจำหลัก = 12
        ' โดยให้หลักที่ 3 คูณด้วยน้ำหนักประจำหลัก = 11
        ' โดยให้หลักที่ .. คูณด้วยน้ำหนักประจำหลัก = ..
        ' โดยให้หลักที่ 12 คูณด้วยน้ำหนักประจำหลัก = 2
        ' จากนั้นนำผลการคูณของแต่ละหลักมารวมกันเข้าไป
        ' หลักแต่ละหลัก คือ Val(Mid$(txtIDcard.Text, Count, 1))
        ' น้ำหนักของแต่ละหลัก คือ (14 - Count) เมื่อ Count เริ่มต้นจาก 1 ไปสิ้นสุดที่ 12
        ' ดังนั้นค่านี้ (14 - Count) จึงเริ่มต้นค่าจาก 13, 12, 11, ..., สิ้นสุดที่ 2 ครับผม
        Dim Sum As Integer = 0
        For Count As Byte = 1 To 12
            Sum = Sum + Val(Mid$(txtIDCard.Text, Count, 1)) * (14 - Count)
        Next
        ' / --------------------------------------------------------------------
        ' ขั้นตอนนี้ คือ การหาค่า Check Digit (หลักที่ 13) หรือ หลักตรวจสอบความถูกต้อง
        ' นำผลรวมที่ได้ (Sum) มา Mod (การหารเอาเศษ) ด้วย 11 นั่นคือค่าที่เราจะได้ก็คือ 0, 1, 2, .. , 10 (Sum Mod 11)
        ' จากนั้นให้ลบออกด้วย 11 ก็จะทำให้ได้ค่าตั้งแต่ 1, 2, 3, ... , 11 (11 - (Sum Mod 11))
        ' แล้วให้เลือกตัวขวามือสุดมาหนึ่งตัว ด้วยคำสั่ง Right$ --> Right$(Str(11 - (Sum Mod 11)), 1)
        ' ค่าสุดท้ายนี้ก็คือ หลักที่ 13 หรือ หลักตรวจสอบความถูกต้อง (Check Digit) นั่นเอง
        '
        Dim CheckDigit As String = Microsoft.VisualBasic.Right(Str(11 - (Sum Mod 11)), 1)
        txtIDCard.Text = txtIDCard.Text + CheckDigit
    End Sub
    ' / --------------------------------------------------------------------
    ' ฟังค์ชั่นที่ใช้ในการสุ่มตัวเลขจำนวน 12 หลัก ไม่มีการรับค่า แต่จะต้องส่งค่าคืนกลับไป (Return)
    ' ดังนั้นเราต้องใช้เป็นแบบฟังค์ชั่น (Function)  จะใช้ Sub Program ไม่ได้
    ' / --------------------------------------------------------------------
    Function RandomNumber() As String
        RandomNumber = String.Empty
        ' เริ่มต้นในการสุ่มตัวเลข
        Randomize()
        Dim rndID As New Random
        '/ เพื่อบ่งบอกว่าหลักแรกหาค่าได้สำเร็จแล้วหรือไม่
        Dim blnFlag As Boolean = False
        Dim i As Byte = 1
        ' สุ่มเลขจำนวน 12 หลัก โดยที่หลักแรกต้องไม่ใช่ 0 และ 9
        ' i เริ่มต้นจาก 1
        While i <> 12
            ' Not False หรือ ไม่จริง ก็คือ เท็จ (หรือเขียน blnFlag = False) ... แสดงว่าตอนนี้เรากำลังจะหาตัวเลขหลักแรกอยู่
            If Not blnFlag Then
                ' สุ่มตัวเลขหลักแรก ต้องไม่ให้มีค่าเป็น 0 และ 9 ... นี่คือการทำซ้ำ หรือ Repetitive
                Do
                    RandomNumber = rndID.Next(0, 9)
                    ' ทำจนกว่าหลักแรกต้องไม่เท่ากับ 0 และ 9 (เงื่อนไขต้องใช้ AND)
                    ' เช่น เมื่อ RandomNumber มีค่า = 1
                    ' ทำให้ได้เงื่อนไข 1 <> 0 และ 1 <> 9 (True AND True = True) ... เงื่อนไขเป็น "จริง" ให้ออกจาก Loop
                    ' หรือ เมื่อ RandomNumber มีค่า = 9
                    ' ทำให้ได้เงื่อนไข 9 <> 0 และ 9 <> 9 (True AND False = False) ... เงื่อนไขเป็น "เท็จ" ให้วน Loop ต่อไป
                Loop Until RandomNumber <> 0 And RandomNumber <> 9
                ' หรือ ใช้เงื่อนไข Until แต่กลับกันด้วย Not ...
                'Loop Until Not RandomNumber = 0 And Not RandomNumber = 9
                ' หรือใช้ While แต่เงื่อนไขต้องกลับกันกับแบบ Until และต้องใช้ OR แทนที่
                ' เช่น เมื่อ RandomNumber มีค่า = 1
                ' ทำให้ได้เงื่อนไข 1 = 0 หรือ 1 = 9 (False OR False = False) ... เงื่อนไขเป็น "เท็จ" ให้ออกจาก Loop
                ' หรือ เมื่อ RandomNumber มีค่า = 9
                ' ทำให้ได้เงื่อนไข 9 = 0 หรือ 9 = 9 (False OR True = True) ... เงื่อนไขเป็น "จริง" ให้วน Loop ต่อไป
                'Loop While RandomNumber = 0 Or RandomNumber = 9
                ' แจ้งว่าหลักแรกหาตัวเลขที่ไม่ใช่ 0 หรือ 9 เสร็จสมบูรณ์แล้ว หลักต่อไปจะได้ไม่ต้องเข้าไป Do Loop อีก
                blnFlag = True
            End If
            ' หาค่าจำนวนหลักที่เหลือ แล้วส่งค่าคืนกลับของฟังค์ชั่นไปได้เลย
            RandomNumber = RandomNumber & rndID.Next(0, 9)
            '// Increment Counter
            i += 1
        End While
    End Function
    ' / --------------------------------------------------------------------
    ' / ตรวจสอบหมายเลขบัตรประชาชน
    Private Sub btnCheck_Click(sender As System.Object, e As System.EventArgs) Handles btnCheck.Click
        '/ ไม่มีการป้อนข้อมูล ก็ให้ออกจากโปรแกรมย่อยไป
        If txtIDCard.Text = "" Or txtIDCard.Text.Trim.Length = 0 Then Exit Sub
        ' ความยาวต้องเท่ากับ 13 หลัก
        If Len(txtIDCard.Text) < 13 Then
            MsgBox("กรุณากรอกหมายเลขบัตรประชาชนให้ครบทั้ง 13 หลักด้วย.", vbOKOnly + vbExclamation, "รายงานความผิดพลาด")
            Exit Sub
        End If
        ' หาผลรวมตั้งแต่หลักที่ 1 ไปจนถึงหลักที่ 12
        Dim Sum As Integer = 0
        For Count As Byte = 1 To 12
            Sum = Sum + Val(Mid(txtIDCard.Text, Count, 1)) * (14 - Count)
        Next
        ' เปรียบเทียบค่าที่ได้กับหลักที่ 13
        If Microsoft.VisualBasic.Right(txtIDCard.Text, 1) = Microsoft.VisualBasic.Right(Str(11 - (Sum Mod 11)), 1) Then
            MessageBox.Show("หมายเลขบัตรประชาชน " & txtIDCard.Text & " ถูกต้อง.", "รายงานการตรวจสอบ", MessageBoxButtons.OK, MessageBoxIcon.Information)
        Else
            MessageBox.Show("หมายเลขบัตรประชาชน " & txtIDCard.Text & " ไม่ถูกต้อง.", "รายงานการตรวจสอบ", MessageBoxButtons.OK, MessageBoxIcon.Exclamation)
        End If
    End Sub
    Private Sub frmCheckIDCard_Load(sender As System.Object, e As System.EventArgs) Handles MyBase.Load
        txtIDCard.Focus()
    End Sub
    Private Sub txtIDCard_KeyPress(sender As Object, e As System.Windows.Forms.KeyPressEventArgs) Handles txtIDCard.KeyPress
        If Asc(e.KeyChar) = 13 Then
            e.Handled = True
            btnCheck_Click(sender, e)
        Else
            e.Handled = CheckDigitOnly(Asc(e.KeyChar))
        End If
    End Sub
    ' / ฟังค์ชั่นในการป้อนเฉพาะค่าตัวเลขได้เท่านั้น
    Function CheckDigitOnly(ByVal index As Integer) As Boolean
        Select Case index
            Case 48 To 57 ' เลข 0 - 9
                CheckDigitOnly = False
            Case 8, 13 ' Backspace = 8, Enter = 13
                CheckDigitOnly = False
            Case Else
                CheckDigitOnly = True
        End Select
    End Function
End Class
 ดาวน์โหลดโค้ดต้นฉบับ VB.NET (2010) ได้จากที่นี่ ...
 
 
 | 
 
xขออภัย! โพสต์นี้มีไฟล์แนบหรือรูปภาพที่ไม่ได้รับอนุญาตให้คุณเข้าถึงคุณจำเป็นต้อง ลงชื่อเข้าใช้ เพื่อดาวน์โหลดหรือดูไฟล์แนบนี้ คุณยังไม่มีบัญชีใช่ไหม? ลงทะเบียน  |