Số không có chữ số kiểm tra là nhóm những chuỗi chỉ mang tính tuần tự, không có thuật toán công khai nào để đối chiếu phần cuối với phần thân. Với nhóm này, một công cụ kiểm tra chỉ có thể làm được ba việc: chuẩn hóa chuỗi, đối chiếu tập ký tự, và đối chiếu độ dài. Kết luận đúng nhất cho chúng là chỉ định dạng, và đây là trạng thái hay bị bỏ qua nhất trong các hệ thống thật. Đọc hết bài này, bạn sẽ biết vì sao việc gán nhãn hợp lệ cho nhóm này là một lỗi thiết kế, và cách xử lý đúng trông như thế nào.
Số không có chữ số kiểm tra là gì?
Đây là những chuỗi được cấp theo kiểu đếm tăng dần hoặc theo một quy tắc phân bổ nội bộ nào đó, và bên cấp không công bố bất kỳ quan hệ toán học nào giữa các vị trí trong chuỗi. Chuỗi có thể có một khuôn dạng bên ngoài rất rõ ràng: chỉ gồm chữ số, hoặc gồm cả chữ cái, hoặc có một tiền tố chỉ cơ quan cấp. Nhưng tính đúng đắn của nó không thể suy ra từ chính nó.
Thiếu chữ số kiểm tra không có nghĩa hệ thống đó kém. Nhiều hệ thống chỉ cần định danh duy nhất một đối tượng và đãi ngộ việc chống gõ nhầm bằng cách khác, ví dụ cấp số ngắn cho dễ đọc, in số thành nhiều nhóm, hoặc kiểm tra ở nguồn dữ liệu mỗi khi tra cứu. Với những hệ thống này, một thuật toán chữ số kiểm tra là không cần thiết.
Điều quan trọng với người làm phần mềm là nhận ra mình đang ở nhóm nào trước khi viết hàm kiểm tra. Nếu bạn đi tìm chữ số kiểm tra cho một chuỗi vốn không có, bạn sẽ dành thời gian cho một thứ không tồn tại, và tệ hơn, có thể tự nghĩ ra một quy tắc rồi áp nó vào dữ liệu thật.
Vì sao nhiều hệ thống chỉ cần số sê-ri?
Chi phí thiết kế một thuật toán chữ số kiểm tra không lớn, nhưng chi phí duy trì nó thì có. Mỗi khi quy tắc đánh số thay đổi, thuật toán và mọi bản triển khai phải cập nhật theo. Với những hệ thống mà số được tra cứu trực tuyến ngay khi sử dụng, lợi ích của việc bắt lỗi tại chỗ có thể không đủ để bù chi phí đó.
Ngoài ra còn có ràng buộc về không gian hiển thị. Số càng ngắn thì càng ít chỗ để nhét thêm một chữ số kiểm tra mà vẫn giữ được đủ không gian cho phần định danh. Với những nhãn bị giới hạn diện tích in, việc bỏ chữ số kiểm tra là một lựa chọn hợp lý.
Cuối cùng, có những hệ thống mà bản thân việc tra cứu đã là bước bắt buộc trong quy trình, nên không cần thêm một lớp kiểm tra cục bộ trước. Hiểu ba lý do này giúp bạn tránh việc đi tìm một quy tắc không tồn tại chỉ vì bạn cho rằng mọi loại số đều phải có chữ số kiểm tra.
Ba tầng: chuẩn hóa, tập ký tự, độ dài
Khi không có chữ số kiểm tra, ba tầng còn lại trở thành toàn bộ phạm vi công việc. Mỗi tầng vẫn cần được làm cẩn thận, vì chúng là những gì duy nhất bạn có thể nói về chuỗi.
- Chuẩn hóa: bỏ ký tự ngăn cách và ký tự trang trí, thống nhất dạng chữ, để hai cách viết của cùng một số cho ra cùng một kết quả.
- Tập ký tự: xác định chuỗi chỉ gồm chữ số, hay được phép có chữ cái, và nếu có chữ cái thì ở vị trí nào.
- Độ dài: xác định độ dài hợp lệ trên chuỗi đã chuẩn hóa, không phải trên chuỗi gốc còn dấu ngăn cách.
Ba tầng này bắt được nhiều lỗi nhập liệu thường gặp: nhập thiếu ký tự, nhập dư ký tự, lẫn ký tự không hợp lệ. Chúng không bắt được lỗi gõ một chữ số thành một chữ số khác ở giữa chuỗi, vì không có gì để đối chiếu. Đó là giới hạn thật của tình huống này, và cách xử lý đúng là nói ra giới hạn đó chứ không phải che đi.
Một cám dỗ cần tránh là tự dựng một quy tắc riêng rồi gọi nó là quy tắc của hệ thống. Ví dụ, dùng một chữ số bất kỳ ở cuối làm điểm kiểm tra theo một công thức tự nghĩ ra. Cách làm này tạo ra những kết luận không hợp lệ và khiến người dùng tin vào một thứ không có cơ sở.
Vì sao không được gán nhãn hợp lệ cho chúng?
Vì nhãn hợp lệ mang một hàm ý rất cụ thể: chuỗi này đã vượt qua một phép kiểm tra đã biết. Nếu không có phép kiểm tra nào được chạy, việc gán nhãn đó là một câu khẳng định sai về mặt kỹ thuật, kể cả khi chuỗi trông có vẻ đúng.
Hệ quả không chỉ là vấn đề ngôn từ. Trong nhiều hệ thống, nhãn hợp lệ được dùng làm điều kiện để cho qua bước tiếp theo, ví dụ để lưu vào cơ sở dữ liệu hoặc để gửi yêu cầu đi. Nếu nhãn đó được gán cho một nhóm không hề được kiểm tra, bạn đã tạo ra một đường đi vòng qua toàn bộ lớp bảo vệ, và đường đi vòng đó khó thấy vì nó nằm trong một nhánh logic trông có vẻ đúng.
Cách làm đúng là giữ một trạng thái riêng cho chỉ định dạng, và để trạng thái đó không bao giờ được coi là tương đương với hợp lệ. Nếu nghiệp vụ bắt buộc phải chấp nhận những chuỗi này, hãy để quyết định đó nằm ở tầng nghiệp vụ, có tên riêng, chứ không phải ở tầng kiểm tra định dạng. Bạn có thể xem cách bốn trạng thái được phân biệt trong thực tế trên công cụ kiểm tra số của trang này.
Phân biệt thiếu quy tắc với số sai
Hai tình huống này trông giống nhau ở tầng giao diện nhưng khác nhau hoàn toàn về ý nghĩa. Thiếu quy tắc là tình huống hệ thống không có gì để đối chiếu. Số sai là tình huống hệ thống có quy tắc, đã đối chiếu, và chuỗi không đạt. Gộp hai tình huống này thành một thông báo là lỗi phổ biến nhất khi thiết kế phần kiểm tra.
Với người dùng, hai tình huống dẫn tới hai hành động khác nhau. Nếu hệ thống nói không có quy tắc, người dùng biết mình phải tự kiểm tra kỹ, hoặc phải hỏi nguồn dữ liệu gốc. Nếu hệ thống nói số không hợp lệ, người dùng biết mình có một chỗ cụ thể để sửa. Một thông báo trung bình cộng làm mất cả hai thông tin.
Với người vận hành, việc gộp nhãn cũng làm mất khả năng thống kê. Nếu mọi chuỗi không đạt đều được ghi chung một mã lỗi, bạn không thể biết tỉ lệ lỗi thật là bao nhiêu và bao nhiêu là do hệ thống thiếu quy tắc. Đây là loại nhầm lẫn dẫn tới những quyết định sai về việc nên bổ sung quy tắc ở đâu.
Phần dành cho nhà phát triển: trạng thái riêng cho chỉ định dạng
Điều nên làm sớm nhất là đặt tên cho trạng thái chỉ định dạng ngay trong mã nguồn, trước cả khi viết hàm kiểm tra đầu tiên. Khi trạng thái này đã có tên, việc gán nhầm nó thành hợp lệ trở nên khó hơn nhiều, vì bạn phải viết rõ ràng một phép so sánh giả để làm điều đó.
- Đừng ánh xạ trạng thái chỉ định dạng sang hợp lệ vì giao diện cần ít màu. Hãy để giao diện hiển thị ba màu nếu nghiệp vụ có ba trạng thái.
- Trả về danh sách những tầng đã chạy và tầng nào không có quy tắc. Đây là thông tin duy nhất giúp người bảo trì hiểu vì sao kết luận dừng lại ở định dạng.
- Cho phép cấu hình theo từng loại số, vì cùng một hệ thống có thể phục vụ nhiều loại số, trong đó một số loại có chữ số kiểm tra và một số loại thì không.
- Viết kiểm thử riêng cho nhánh không có quy tắc. Nhánh này thường không bao giờ được chạy trong quá trình phát triển, nên nó là nơi lỗi ẩn náu lâu nhất.
- Ghi lại nguồn của quyết định rằng loại số này không có thuật toán công khai. Khi có người hỏi vì sao hệ thống không kiểm tra, bạn cần một câu trả lời có căn cứ.
- Đừng để thông báo lỗi nói rằng số này là giả. Chỉ nói rằng chưa có quy tắc để đối chiếu. Đây là khác biệt giữa một thông báo đúng và một thông báo gây hiểu nhầm.
Một khi nhánh này được xử lý đúng, chất lượng dữ liệu đầu vào của bạn tăng lên mà không cần thêm bất kỳ thuật toán nào.
Điều nên làm sau bài này
Hãy rà lại danh sách các loại số mà hệ thống của bạn đang nhận, và đánh dấu loại nào thật sự có thuật toán công khai, loại nào chỉ có định dạng. Nếu danh sách của bạn chưa có cột đó, bạn đang không biết mình kiểm tra được gì. Để hiểu trọn vẹn ba tầng còn lại, bài kiểm tra số: ký tự, độ dài và chữ số kiểm tra là điểm bắt đầu phù hợp; còn bài kiểm tra tại API: nên chặn ở máy khách hay máy chủ nói về việc đặt những quyết định này ở tầng nào trong hệ thống. Nếu dữ liệu của bạn gắn với địa chỉ và số điện thoại, bài kiểm thử địa chỉ và số điện thoại quốc tế có thêm ví dụ về cùng kiểu giới hạn.
Mọi chuỗi được nhắc tới trong bài chỉ dùng để minh họa sự khác biệt giữa các tầng kiểm tra; chúng không phải số của bất kỳ đối tượng nào có thật, không thuộc bất kỳ tổ chức nào, và không được dùng để mạo danh hay để khẳng định một con số là dùng được hay không dùng được.