|
|

โค้ด VB.NET ในการสร้าง QR Code แบบกำหนดจำนวนเงิน (หรือที่เรียกว่า Dynamic QR Code) เพื่อให้ผู้อื่นสแกนและชำระเงินตามจำนวนที่เราล็อกยอดไว้ จุดประสงค์ก็เพื่ออำนวยความสะดวกให้กับผู้โอนเงินและผู้รับเงิน จะได้ไม่มีข้อผิดพลาดในเรื่องของจำนวนเงิน ข้อมูลทั้งหมดเกี่ยวกับรูปแบบ QR Code พร้อมเพย์ ไม่ได้เป็นข้อมูลความลับแต่อย่างใด เป็นมาตรฐานที่ ** ธนาคารแห่งประเทศไทย ประกาศเผยแพร่อย่างเป็นทางการ ** เพื่อให้ทุกคนและหน่วยงานสามารถนำไปใช้งานได้อย่างถูกต้องครับ ไม่มีลิขสิทธิ์ห้ามเผยแพร่ครับผม ...
หลักการทำงานสร้าง QR พร้อมเพย์ แบบสรุป 4 ขั้นตอน ...
### เตรียมข้อมูลผู้รับเงิน
- เบอร์โทร --> แปลงเป็นรูปแบบสากล เช่น 0812345678 --> 0066812345678
- หรือ เลขบัตรประชาชน 13 หลัก
- ใส่ลงในรูปแบบ **รหัส-ความยาว-ค่า** เช่น 01130066812345678
### ประกอบชุดข้อมูลหลัก (Payload) เรียงข้อมูลตามลำดับมาตรฐาน:
ส่วน หน้าที่
Tag 00 เวอร์ชันมาตรฐาน = 01
Tag 01 ประเภท: มีเงิน = 12 / ไม่มี = 11
Tag 29 ข้อมูลบัญชีผู้รับ (เบอร์/บัตร)
Tag 53 รหัสสกุลเงิน = 764 = บาทไทย
Tag 54 จำนวนเงิน (ถ้ามี) เช่น 100.50
Tag 58 รหัสประเทศ = TH
### คำนวณค่าตรวจสอบ CRC (Cyclic Redundancy Check)
- นำข้อความทั้งหมดที่ประกอบเสร็จแล้ว มาคำนวณ **CRC16-CCITT**
- ต่อท้ายข้อความด้วย 6304 + ค่า CRC 4 หลัก เช่น 6304A3B5
- เพื่อให้แอพธนาคารตรวจสอบว่าข้อมูลถูกต้อง ไม่ผิดพลาด
### สร้างภาพ QR Code
- นำข้อความทั้งหมดที่ได้ ส่งให้ไลบรารีสร้างภาพ QR Code (ใช้ของฟรี ZXing ในการแปลงข้อความเป็น QR Code)
- เสร็จเรียบร้อย สแกนจ่ายเงินได้เลยครับ
หมายเหตุ:
โค้ดที่แอดมินได้แจกจ่ายออกไปจะเป็นแบบ CopyLeft หรือ MIT License โดยที่ ...
- ให้ใช้ได้อย่างอิสระ แค่อย่าแอบอ้างและรับผิดเอง
- ใส่ชื่อเจ้าของเดิมไว้ ไม่ต้องกราบไหว้ แค่บอกไว้ว่าใครเป็นคนทำเดิมก็พอ
- ถ้ามีอะไรพังหรือเกิดความเสียหาย เจ้าของโค้ดไม่ต้องรับผิดชอบ ใช้ไปแล้วเกิดปัญหา เป็นหน้าที่ของคนที่นำไปใช้ครับ ไม่ใช่หน้าที่คนทำเดิม

Add References ...
เครื่องมือหรือ Component ของฟรีที่นำมาใช้งาน
- SunnyUI ทำ GUI (Graphices User Interface)
- ZXing เอาไว้แปลงข้อความให้เป็น QR Code
มาดูโค้ดฉบับเต็มกันเถอะ ...
- '// ZXing.Net release download.
- '// https://github.com/micjahn/ZXing.Net/releases
- '// แนวนโยบายการใช้มาตรฐาน Thai QR Code ในธุรกรรมการชำระเงิน ธนาคารแห่งประเทศไทย
- '// https://www.bot.or.th/content/dam/bot/fipcs/documents/FPG/2562/ThaiPDF/25620084.pdf
- Imports System.Globalization
- Imports System.Text
- Imports ZXing
- Imports ZXing.Common
- Imports ZXing.QrCode
- Imports ZXing.Rendering
- Imports System.IO
- Imports System.Drawing.Imaging
- Imports Sunny.UI
- Public Class frmQRCodePromptPay
- Private Sub frmQRCodePromptPay_KeyDown(sender As Object, e As System.Windows.Forms.KeyEventArgs) Handles Me.KeyDown
- Select Case e.KeyCode
- Case Keys.F3
- btnGenerate.PerformClick()
- Case Keys.F10
- Me.Close()
- End Select
- End Sub
- Private Sub frmQRCodePromptPay_Load(sender As System.Object, e As System.EventArgs) Handles MyBase.Load
- ' SunnyUI
- UIStyles.CultureInfo = CultureInfos.en_US
- '// เปิดใช้งานการตั้งค่าฟอนต์ทั่วทั้งแอพพลิเคชัน
- UIStyles.GlobalFont = True
- '// กำหนดชื่อฟอนต์ที่ต้องการใช้ เช่น "TH Sarabun New" หรือ "Segoe UI"
- UIStyles.GlobalFontName = "Tahoma" '"Segoe UI"
- '// ตั้งค่าขนาดฟอนต์ (100 คือขนาด 12pt, 75 คือขนาด 9pt, 125 คือขนาด 15pt)
- UIStyles.GlobalFontScale = 100
- '// บังคับให้ UI รีเฟรชเพื่อใช้การตั้งค่าใหม่
- UIStyles.SetDPIScale()
- ' Form
- Me.KeyPreview = True ' ใช้สำหรับการกดปุ่มฟังค์ชั่นต่างๆได้
- txtAccount.Text = ""
- txtAmount.Text = ""
- txtPayload.Text = ""
- End Sub
- ' /-----------------------------------------------------------------------------
- ' Select All ข้อมูลทั้งหมดใน UiTextBox ของ SunnyUI
- Private Sub frmQRCodePromptPay_Shown(sender As Object, e As System.EventArgs) Handles Me.Shown
- Me.BeginInvoke(New MethodInvoker(
- Sub()
- txtAccount.Focus()
- txtAccount.SelectAll()
- End Sub))
- End Sub
- ' /-----------------------------------------------------------------------------
- ' / นำค่าจาก txtPayload เพื่อทำการสร้าง QRCode Payload ด้วย ZXing
- ' /-----------------------------------------------------------------------------
- Private Sub txtPayload_TextChanged(sender As Object, e As EventArgs) Handles txtPayload.TextChanged
- If String.IsNullOrWhiteSpace(txtPayload.Text) Then
- picQRCode.Image = Nothing
- Return
- End If
- '//
- Dim options As EncodingOptions = New QrCodeEncodingOptions
- With options
- .NoPadding = True
- .Width = picQRCode.Width
- .Height = picQRCode.Height
- .Hints.Add(EncodeHintType.CHARACTER_SET, "UTF-8")
- .PureBarcode = False
- End With
- '//
- Dim objWriter As BarcodeWriter = New BarcodeWriter With {
- .Format = BarcodeFormat.QR_CODE,
- .Options = options,
- .Renderer = New BitmapRenderer
- }
- picQRCode.Image = New Bitmap(objWriter.Write(txtPayload.Text))
- picQRCode.SizeMode = PictureBoxSizeMode.StretchImage
- End Sub
- ' /-----------------------------------------------------------------------------
- ' / สร้าง QR พร้อมยอดเงิน
- ' /-----------------------------------------------------------------------------
- Private Sub btnGenerate_Click(sender As Object, e As EventArgs) Handles btnGenerate.Click
- ' อ่านค่า
- Dim amount As Decimal = 0D
- Decimal.TryParse(txtAmount.Text.Trim(), amount)
- amount = Math.Abs(amount)
- ' เรียกสร้าง Payload (ตรวจสอบเองภายใน ถ้าผิดจะแจ้งและคืนค่าว่าง)
- Dim payload As String = BuildPromptPayPayload(txtAccount.Text.Trim(), amount)
- ' ตรวจสอบผลลัพธ์
- If payload = "" Then
- txtAccount.Focus()
- Exit Sub
- End If
- ' แสดงผล
- txtPayload.Text = payload
- txtAccount.Focus()
- End Sub
- ' /-----------------------------------------------------------------------------
- ' / ประกอบ Tag-Length-Value ตามมาตรฐาน EMVCo
- ' /-----------------------------------------------------------------------------
- Private Function TagLengthValue(ByVal tagId As String, ByVal value As String) As String
- Return tagId & value.Length.ToString("00") & value
- End Function
- ' /-----------------------------------------------------------------------------
- ' / แปลงเบอร์โทรเป็นรูปแบบสากล
- ' /-----------------------------------------------------------------------------
- Private Function FormatPhoneNumber(ByVal phone As String) As String
- Dim digits As String = New String(phone.Where(AddressOf Char.IsDigit).ToArray())
- If digits.Length = 10 AndAlso digits.StartsWith("0") Then
- Return "0066" & digits.Substring(1)
- ElseIf digits.Length = 9 Then
- Return "0066" & digits
- ElseIf digits.Length = 11 AndAlso digits.StartsWith("66") Then
- Return "00" & digits
- End If
- Return digits
- End Function
- ' /-----------------------------------------------------------------------------
- ' / สร้าง Payload PromptPay/พร้อมเพย์ มาตรฐานรองรับทุกธนาคาร
- ' / การคืนค่า = สำเร็จจะคืนค่า Payload String , หากไม่สำเร็จ คืนค่าว่าง
- ' /-----------------------------------------------------------------------------
- Public Function BuildPromptPayPayload(ByVal target As String, ByVal amount As Decimal) As String
- ' เก็บเฉพาะตัวเลข
- Dim id As String = New String(target.Where(AddressOf Char.IsDigit).ToArray())
- Dim subTag As String = ""
- Dim targetType As String = ""
- ' ตรวจสอบว่าเลือกเบอร์หรือบัตรประชาชน จากภายนอกไม่ได้ (ตรวจตามความยาวแทน)
- ' เบอร์โทรศัพท์ ยาว 10 หลัก
- If id.Length = 10 Then
- ' เบอร์โทร
- Dim formattedPhone As String = FormatPhoneNumber(id)
- If formattedPhone.Length = 13 AndAlso formattedPhone.StartsWith("0066") Then
- subTag = TagLengthValue("01", formattedPhone) ' 011300668XXXXXXXX เมื่อ X คือเบอร์โทร 8 หลักขวาสุดของเรา
- targetType = "เบอร์โทร"
- Else
- UIMessageBox.ShowMessageDialog("รูปแบบเบอร์โทรไม่ถูกต้อง", "แจ้งเตือน", False, UIStyle.Red, MessageBoxButtons.OK, MessageBoxIcon.Exclamation)
- Return ""
- End If
- ' หมายเลขบัตรประชาชน 13 หลัก
- ElseIf id.Length = 13 Then
- ' ตรวจสอบความถูกต้องของบัตรประชาชน / เลขผู้เสียภาษี
- If Not CheckCorrectID(id) Then
- UIMessageBox.ShowMessageDialog("เลขบัตรประจำตัวประชาชนไม่ถูกต้อง", "แจ้งเตือน", False, UIStyle.Red, MessageBoxButtons.OK, MessageBoxIcon.Exclamation)
- Return ""
- End If
- subTag = TagLengthValue("02", id)
- targetType = "บัตรประชาชน"
- Else
- UIMessageBox.ShowMessageDialog("รูปแบบไม่ถูกต้อง" & vbCrLf & "เบอร์โทร : 10 หลัก (เริ่มต้นด้วย 0)" & vbCrLf & "บัตรประชาชน : 13 หลัก", "แจ้งเตือน", False, UIStyle.Red, MessageBoxButtons.OK, MessageBoxIcon.Exclamation)
- Return ""
- End If
- ' ข้อมูลผู้รับเงิน
- Dim merchantInfo As String = TagLengthValue("00", "A000000677010111") & subTag
- ' ประกอบ Payload หลัก
- Dim sb As New StringBuilder()
- ' Tag 00: เวอร์ชัน
- sb.Append(TagLengthValue("00", "01"))
- ' Tag 01: ประเภทธุรกรรม
- ' 11 = เรียกเก็บเงินซ้ำได้ / 12 = จ่ายครั้งเดียว
- If amount > 0D Then
- sb.Append(TagLengthValue("01", "12"))
- Else
- sb.Append(TagLengthValue("01", "11"))
- End If
- ' Tag 29: ข้อมูลบัญชีผู้รับ
- sb.Append(TagLengthValue("29", merchantInfo))
- ' Tag 53: รหัสสกุลเงิน 764 = บาทไทย
- sb.Append(TagLengthValue("53", "764"))
- ' Tag 54: จำนวนเงิน (ถ้ามี)
- If amount > 0D Then
- ' ใช้จุดทศนิยมเสมอ ไม่สนใจ Culture
- Dim amountStr As String = amount.ToString("0.00", CultureInfo.InvariantCulture)
- sb.Append(TagLengthValue("54", amountStr))
- End If
- ' Tag 58: รหัสประเทศ
- sb.Append(TagLengthValue("58", "TH"))
- ' คำนวณ CRC ท้ายสุด
- Dim crcBase As String = sb.ToString() & "6304"
- Dim crcValue As String = CalcCRC16(crcBase)
- sb.Append("6304" & crcValue)
- Return sb.ToString()
- End Function
- ' /-----------------------------------------------------------------------------
- ' / คำนวณ CRC16‑CCITT (รูปแบบ 0x1021, ค่าเริ่มต้น 0xFFFF)
- ' /-----------------------------------------------------------------------------
- ' / CRC ย่อมาจาก Cyclic Redundancy Check คือ "รหัสตรวจสอบความถูกต้องของข้อมูล"
- ' / ใช้ทำอะไรใน QR พร้อมเพย์?
- ' / - ตามมาตรฐาน EMVCo บังคับให้ 4 หลักสุดท้ายของข้อความ QR เป็นค่า CRC
- ' / ที่คำนวณจากข้อมูลทั้งหมดก่อนหน้า
- ' /
- ' / - ฝั่งเรา (สร้าง QR) : คำนวณค่า CRC แล้วต่อท้ายข้อความเสมอ
- ' / - ฝั่งแอพธนาคาร (สแกน) : คำนวณ CRC ใหม่จากข้อมูลที่อ่านได้
- ' / แล้วเปรียบเทียบกับค่าที่ติดมากับ QR
- ' / - ถ้าไม่ตรงกัน - แอพปฏิเสธทันที เพราะข้อมูลอาจเสียหายหรือถูกแก้ไข
- ' /-----------------------------------------------------------------------------
- Private Function CalcCRC16(ByVal data As String) As String
- ' ตั้งค่าเริ่มต้นตามมาตรฐาน: 16 บิตเริ่มเป็น 1 ทั้งหมด = 0xFFFF
- Dim crc As Integer = &HFFFFI ' I = บอกว่าค่านี้เป็นชนิด Integer (จำนวนเต็ม 32 บิต)
- ' แปลงข้อความเป็นไบต์ ASCII เพราะ CRC คำนวณทีละไบต์ Payload ของ PromptPay
- ' เป็นตัวเลขและตัวอักษรอังกฤษเท่านั้น จึงใช้ ASCII ได้
- Dim bytes() As Byte = Encoding.ASCII.GetBytes(data)
- ' ประมวลผลทีละค่า ทีละตัว
- For Each b As Byte In bytes
- ' นำแต่ละไบต์มาเลื่อนไปทางซ้าย 8 บิต เพื่อให้ไปตรงกับไบต์สูงของ CRC แล้ว XOR เข้าไป
- crc = crc Xor (CInt(b) << 8)
- ' คำนวณทีละ 1 บิต รวม 8 รอบต่อ 1 ค่า
- For i As Integer = 0 To 7
- ' เช็กเลขตัวแรกทางซ้ายว่าเป็น 1 หรือไม่
- If (crc And &H8000I) <> 0 Then
- ' เป็น 1 - เลื่อนค่าทางซ้าย 1 ตำแหน่ง ผสมกับรูปแบบ 0x1021
- ' (&H1021 คือ ค่าคงที่มาตรฐานที่ทุกคนตกลงกันใช้สำหรับ CRC16‑CCITT)
- ' And &HFFFFI บังคับให้ค่าคงเหลือแค่ 16 บิตเสมอ ไม่ให้เกิน
- crc = ((crc << 1) Xor &H1021I) And &HFFFFI
- Else
- ' เป็น 0 - เลื่อนทางซ้ายอย่างเดียว
- ' And &HFFFFI บังคับให้ค่าคงเหลือแค่ 16 บิตเสมอ ไม่ให้เกิน
- crc = (crc << 1) And &HFFFFI
- End If
- Next
- Next
- 'Debug.Print(crc)
- ' แปลงผลลัพธ์เป็นเลขฐาน 16 ตัวพิมพ์ใหญ่ ยาว 4 หลักเสมอ
- ' เติม 0 ข้างหน้าถ้าน้อยกว่า 4 หลัก เช่น "AB" --> "00AB"
- Return crc.ToString("X4")
- End Function
- ' /-----------------------------------------------------------------------------
- ' / บันทึก QR Code ให้เป็นไฟล์ภาพ
- ' /-----------------------------------------------------------------------------
- Private Sub btnSaveQRCode_Click(sender As Object, e As EventArgs) Handles btnSaveQRCode.Click
- Const TARGET_SIZE As Integer = 256 ' กำหนดขนาดภาพที่ต้องการ
- ' ตรวจสอบว่ามีภาพหรือไม่
- If picQRCode.Image Is Nothing Then
- UIMessageBox.ShowMessageDialog("ยังไม่มีภาพ QR Code ที่จะบันทึก", "แจ้งเตือน", False, UIStyle.Red, MessageBoxButtons.OK, MessageBoxIcon.Warning)
- Exit Sub
- End If
- ' บันทึกไฟล์
- Dim dlgSaveFile As New SaveFileDialog()
- With dlgSaveFile
- .Title = "บันทึกไฟล์ QRCode เป็นภาพ"
- .Filter = "JPEG Image (*.jpg)|*.jpg|Png Image (*.png)|*.png|Bitmap Image (*.bmp)|*.bmp"
- .FilterIndex = 1
- .RestoreDirectory = True
- End With
- If dlgSaveFile.ShowDialog() = DialogResult.OK Then
- Dim resizedImage As Bitmap = Nothing
- Dim fs As FileStream = Nothing
- Try
- ' สร้างภาพใหม่ขนาด 256 x 256
- resizedImage = New Bitmap(TARGET_SIZE, TARGET_SIZE)
- Dim g As Graphics = Graphics.FromImage(resizedImage)
- ' ตั้งค่าคุณภาพการวาด
- g.InterpolationMode = Drawing2D.InterpolationMode.HighQualityBicubic
- g.SmoothingMode = Drawing2D.SmoothingMode.AntiAlias
- g.PixelOffsetMode = Drawing2D.PixelOffsetMode.HighQuality
- ' เติมพื้นหลังสีขาว แล้ววาด QR Code ลงไป
- g.Clear(Color.White)
- g.DrawImage(picQRCode.Image, 0, 0, TARGET_SIZE, TARGET_SIZE)
- g.Dispose() ' ปล่อยหน่วยความจำทันทีเมื่อวาดเสร็จ
- ' เปิดไฟล์และบันทึก
- fs = CType(dlgSaveFile.OpenFile(), FileStream)
- Select Case dlgSaveFile.FilterIndex
- Case 1
- resizedImage.Save(fs, ImageFormat.Jpeg)
- Case 2
- resizedImage.Save(fs, ImageFormat.Png)
- Case 3
- resizedImage.Save(fs, ImageFormat.Bmp)
- End Select
- fs.Close()
- UIMessageBox.ShowMessageDialog("บันทึกไฟล์ภาพ QRCode เรียบร้อยแล้ว.", "รายงานสถานะ", _
- False, _
- UIStyle.Green, _
- MessageBoxButtons.OK, _
- MessageBoxIcon.Information)
- Catch ex As Exception
- UIMessageBox.ShowMessageDialog("เกิดข้อผิดพลาด: " & ex.Message, "ผิดพลาด", MessageBoxButtons.OK, MessageBoxIcon.Error)
- Finally
- ' ทำความสะอาดหน่วยความจำ
- If fs IsNot Nothing Then fs.Dispose()
- If resizedImage IsNot Nothing Then resizedImage.Dispose()
- End Try
- End If
- End Sub
- ' /-----------------------------------------------------------------------------
- ' / คัดลอก QR Code สู่คลิปบอร์ดเพื่อนำไปวางแปะในเอกสาร
- ' /-----------------------------------------------------------------------------
- Private Sub btnClipboard_Click(sender As System.Object, e As System.EventArgs) Handles btnClipboard.Click
- ' ตรวจสอบว่ามีภาพหรือไม่
- If picQRCode.Image Is Nothing Then
- UIMessageBox.ShowMessageDialog( _
- "ยังไม่มีภาพ QR Code ที่จะคัดลอก", _
- "แจ้งเตือน", _
- False, _
- UIStyle.Red, _
- MessageBoxButtons.OK, _
- MessageBoxIcon.Information)
- Exit Sub
- End If
- Try
- ' ========== คัดลอกภาพโดยตรง ==========
- Clipboard.Clear()
- Clipboard.SetImage(picQRCode.Image)
- Catch ex As Exception
- ' จัดการข้อผิดพลาด
- UIMessageBox.ShowMessageDialog( _
- "เกิดข้อผิดพลาด: " & ex.Message, _
- "ผิดพลาด", _
- False, _
- UIStyle.Red, _
- MessageBoxButtons.OK, _
- MessageBoxIcon.Error)
- End Try
- txtAccount.Focus()
- txtAccount.SelectAll()
- End Sub
- Private Sub btnExit_Click(sender As System.Object, e As System.EventArgs) Handles btnExit.Click
- Me.Close()
- End Sub
- Private Sub frmQRCodePromptPay_FormClosed(sender As Object, e As System.Windows.Forms.FormClosedEventArgs) Handles Me.FormClosed
- Me.Dispose()
- GC.SuppressFinalize(Me)
- Application.Exit()
- End Sub
- Private Sub txtAmount_Enter(sender As Object, e As System.EventArgs) Handles txtAmount.Enter
- txtAmount.SelectAll()
- End Sub
- Private Sub txtAmount_KeyDown(sender As Object, e As System.Windows.Forms.KeyEventArgs) Handles txtAmount.KeyDown
- If e.KeyCode = 13 Then
- btnGenerate.PerformClick()
- e.Handled = True
- End If
- End Sub
- Private Sub txtReference_KeyPress(sender As Object, e As System.Windows.Forms.KeyPressEventArgs) Handles txtPayload.KeyPress
- e.Handled = True
- End Sub
- Private Sub txtAccount_Enter(sender As Object, e As System.EventArgs) Handles txtAccount.Enter
- txtAccount.SelectAll()
- End Sub
- Private Sub txtAccount_KeyPress(sender As Object, e As System.Windows.Forms.KeyPressEventArgs) Handles txtAccount.KeyPress
- If Asc(e.KeyChar) = Keys.Enter Then
- e.Handled = True
- SendKeys.Send("{TAB}")
- Else
- e.Handled = CheckDigitOnly(Asc(e.KeyChar))
- End If
- End Sub
- Private Sub ToolStripStatusLabel2_Click(sender As System.Object, e As System.EventArgs) Handles ToolStripStatusLabel2.Click
- Process.Start("https://www.facebook.com/g2gnet")
- End Sub
- #Region "FUNCTION"
- ' ฟังค์ชั่นในการตรวจสอบความถูกต้องของหลักที่ 13 บัตรประชาชน
- Private Function CheckCorrectID(ByVal ID As String) As Boolean
- CheckCorrectID = False
- Dim Sum As Integer
- Dim Count As Short
- '// หลักการคิด
- ' หาผลรวมตั้งแต่หลักที่ 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 ครับผม
- ' หลักที่ 3 ที่มีน้ำหนักประจำหลัก 11 นั่นแหละคือที่เรากำลังพูดถึง
- Sum = 0
- For Count = 1 To 12
- Sum = Sum + Val(Mid(ID, Count, 1)) * (14 - Count)
- Next
- ' วิธีการคิดความถูกต้องของหลักที่ 13 (Check Digit)
- ' จากนั้นให้ลบออกด้วย 11 ก็จะทำให้ได้ค่าตั้งแต่ 1, 2, 3, ... , 11 (11 - (Sum Mod 11))
- ' แล้วให้เลือกตัวขวามือสุดมาหนึ่งตัว ด้วยคำสั่ง Right --> Right(Str(11 - (Sum Mod 11)), 1)
- ' สุดท้ายก็ให้นำมาเปรียบเทียบกับหลักที่ 13 ของหมายเลขบัตรประชาชน ว่ามันตรงกันหรือไม่ ?
- ' หากตรงกันก็แสดงว่า เป็นบัตรแท้, หากไม่ตรงกัน ก็คือ บัตรเก๊ เท่านี้เองครับพี่น้อง
- If Microsoft.VisualBasic.Right(ID, 1) = Microsoft.VisualBasic.Right(Str(11 - (Sum Mod 11)), 1) Then Return True
- End Function
- ' /-----------------------------------------------------------------------------
- ' / ฟังก์ชั่นในการป้อนเฉพาะค่าตัวเลขได้เท่านั้น
- ' / คืนค่า True = ไม่อนุญาตให้พิมพ์, False = อนุญาตให้พิมพ์
- ' /-----------------------------------------------------------------------------
- Function CheckDigitOnly(ByVal keyAscii As Integer) As Boolean
- ' อนุญาต: 0-9, Backspace, Enter, Tab, Delete
- Select Case keyAscii
- ' ตัวเลข 0-9
- Case 48 To 57
- ' Backspace, Tab, Enter
- Case 8, 9, 13
- ' Delete
- Case 46
- Case Else
- Return True ' ไม่อนุญาต
- End Select
- Return False ' อนุญาต
- End Function
- #End Region
- End Class
คัดลอกไปที่คลิปบอร์ด
ดาวน์โหลดโค้ดต้นฉบับ VB.NET (2010) แบบตัวเต็ม ...
|
ขออภัย! โพสต์นี้มีไฟล์แนบหรือรูปภาพที่ไม่ได้รับอนุญาตให้คุณเข้าถึง
คุณจำเป็นต้อง ลงชื่อเข้าใช้ เพื่อดาวน์โหลดหรือดูไฟล์แนบนี้ คุณยังไม่มีบัญชีใช่ไหม? ลงทะเบียน
x
|