2012-10-11 26 views
5

Phiên bản ngắn: Làm cách nào để biến chuỗi tùy ý thành số có 6 chữ số với các va chạm tối thiểu?Tạo ISBN giả từ tên sách? (Hoặc: Cách băm chuỗi thành ID số gồm 6 chữ số)

phiên bản Long:

Tôi đang làm việc với một thư viện nhỏ mà có một loạt các cuốn sách không có ISBN. Đây thường là các tiêu đề cũ hơn, không còn xuất bản từ các nhà xuất bản nhỏ mà không bao giờ có ISBN để bắt đầu, và tôi muốn tạo các ISBN giả để họ có thể giúp quét mã vạch và cho vay.

Về mặt kỹ thuật, ISBN thực được kiểm soát bởi các thực thể thương mại, nhưng có thể sử dụng định dạng để gán số không thuộc về nhà xuất bản thực (và do đó không nên gây ra bất kỳ xung đột nào).

Định dạng là như vậy mà:

978-0-01-######-? 

Cung cấp cho bạn 6 chữ số để làm việc với, 000.000-999.999, với sự? cuối cùng là một kiểm tra.

Bạn có thể chuyển tựa đề sách tùy ý thành số có 6 chữ số trong lược đồ này với cơ hội va chạm tối thiểu không?

+1

Tại sao không chỉ định chúng tuần tự? –

+1

Tôi nghĩ bạn cần khoảng ~ 1000 cuốn sách để có 50% cơ hội va chạm? – Mehrdad

+0

@Damien_The_Unbeliever: Không thể, vì danh sách tiêu đề luôn thay đổi và phần mềm chúng tôi đang sử dụng (trong trường hợp này, Readerware, chương trình quản lý thư viện người tiêu dùng) không cho phép chúng tôi thao tác cơ sở dữ liệu ở cấp đó và tiếp tục theo dõi các ID duy nhất. Việc gắn ID vào tên sách là cách duy nhất tôi có thể nghĩ để làm cho ID tồn tại trong quá trình xuất/nhập CSV vào cơ sở dữ liệu nội bộ Readerware. – arcataroger

Trả lời

0

6 chữ số cho phép khoảng 10M giá trị có thể, là đủ cho hầu hết các mục đích sử dụng nội bộ. Tôi đã sử dụng một chuỗi thay vì trong trường hợp này, bởi vì kiểm tra 6 chữ số có cơ hội va chạm tương đối cao.

Vì vậy, bạn có thể chèn tất cả các chuỗi vào một băm và sử dụng các số chỉ mục làm ISBN, sau khi sắp xếp hoặc không có nó.
Điều này sẽ gây ra va chạm gần như không thể, nhưng nó đòi hỏi phải giữ một số ISBN "được phân bổ" để tránh va chạm trong tương lai và giữ danh sách các tựa đề đã có trong kho, nhưng đó là thông tin mà bạn có thể muốn giữ dù sao.

lựa chọn khác là để phá vỡ các tiêu chuẩn ISBN và sử dụng hệ thập lục phân/mã vạch UUEncoded, có thể tăng phạm vi có thể đến một điểm mà nó có thể làm việc với một băm mật mã cắt ngắn để phù hợp.

Tôi sẽ đề nghị rằng vì bạn đang xử lý các tiêu đề sách cũ, có thể có nhiều phiên bản viết hoa và dấu câu khác nhau, tôi sẽ phân cách dấu chấm câu, sao trắng và chuyển đổi mọi thứ thành chữ thường trước khi so sánh để giảm thiểu cơ hội trùng lặp kỹ thuật mặc dù chuỗi khác (Trừ khi bạn muốn các ấn bản khác nhau có các ISBN khác nhau, trong trường hợp đó, bạn có thể bỏ qua đoạn này).

+0

Tôi không nghĩ rằng các số tuần tự sẽ hoạt động, bởi vì trong quy trình làm việc này, tôi không thấy bất kỳ cách nào để theo dõi các số đã được sử dụng. Đây là cách nó hoạt động ngay bây giờ: 1. danh sách xuất khẩu của cuốn sách từ thư viện phần mềm của chúng tôi (Readerware) vào CSV 2. Chạy mã này, mà gán ISBN sách mà không có một trong CSV 3 Reimport CSV vào Readerware, thay thế các ISBN bị thiếu với những cái giả (tiếp theo) – arcataroger

+1

Nhưng sau này, khi chúng ta lặp lại quá trình này với các tiêu đề mới, chúng ta phải làm lại điều này. Và nếu chúng ta mất một bản sao của một cuốn sách, hãy lấy một cuốn sách sau và thêm lại nó vào cơ sở dữ liệu, nó sẽ không có ISBN riêng biệt từ bản sao đầu tiên. Và toàn bộ quá trình này phải tồn tại các máy tính khác nhau chạy cả chương trình thư viện và tiện ích, điều này có nghĩa là các ID tuần tự sẽ được lưu ở đâu đó trực tuyến và tôi phải lo lắng về vấn đề đồng bộ hóa và tất cả ... giống như một kịch bản ác mộng so với việc kết hợp nó với các tựa sách, mà chúng ta có thể giả định là duy nhất và ổn định. – arcataroger

+1

Tôi đồng ý rằng việc giữ một danh sách số liên tiếp có vấn đề để làm việc với, Điều này sẽ yêu cầu phải có một danh sách (hoặc cơ sở dữ liệu) phụ thêm với tiêu đề và ISBN của chúng sẽ không loại bỏ tiêu đề nếu chúng bị mất, vì vậy khi chúng được tìm thấy hoặc được phản ứng lại, họ sẽ có thể sử dụng cùng một ISBN. Làm cho thuật toán băm duy nhất cho phạm vi này sẽ phức tạp hơn nhiều so với việc giữ một tệp các ISBN đã được chỉ định và tên sách. –

1

Sau khi sử dụng đoạn mã cho making a fixed-length hash và tính toán ISBN-13 checksum, tôi đã quản lý để tạo mã C# thực sự xấu xí dường như hoạt động. Nó sẽ lấy một chuỗi tùy ý và chuyển đổi nó thành một hợp lệ (nhưng giả) ISBN-13:

 public int GetStableHash(string s) 
     { 
      uint hash = 0; 
      // if you care this can be done much faster with unsafe 
      // using fixed char* reinterpreted as a byte* 
      foreach (byte b in System.Text.Encoding.Unicode.GetBytes(s)) 
      { 
       hash += b; 
       hash += (hash << 10); 
       hash ^= (hash >> 6);  
      } 
      // final avalanche 
      hash += (hash << 3); 
      hash ^= (hash >> 11); 
      hash += (hash << 15); 
      // helpfully we only want positive integer < MUST_BE_LESS_THAN 
      // so simple truncate cast is ok if not perfect 
      return (int)(hash % MUST_BE_LESS_THAN); 
     } 

     public int CalculateChecksumDigit(ulong n) 
     { 
      string sTemp = n.ToString(); 
      int iSum = 0; 
      int iDigit = 0; 

      // Calculate the checksum digit here. 
      for (int i = sTemp.Length; i >= 1; i--) 
      { 
       iDigit = Convert.ToInt32(sTemp.Substring(i - 1, 1)); 
       // This appears to be backwards but the 
       // EAN-13 checksum must be calculated 
       // this way to be compatible with UPC-A. 
       if (i % 2 == 0) 
       { // odd 
        iSum += iDigit * 3; 
       } 
       else 
       { // even 
        iSum += iDigit * 1; 
       } 
      } 
      return (10 - (iSum % 10)) % 10; 
     } 


     private void generateISBN() 
     { 
      string titlehash = GetStableHash(BookTitle.Text).ToString("D6"); 
      string fakeisbn = "978001" + titlehash; 
      string check = CalculateChecksumDigit(Convert.ToUInt64(fakeisbn)).ToString(); 

      SixDigitID.Text = fakeisbn + check; 
     } 
Các vấn đề liên quan