2010-07-21 29 views

Trả lời

2

Tôi tìm thấy this thread để đủ rõ ràng, nó cũng chứa (ví dụ) các ví dụ thậm chí khó khăn, chúng là những ví dụ khá 'cực đoan' ở đó. Một ví dụ 'thực tế' hơn bằng cách sử dụng thẻ IMPLICIT có thể được tìm thấy trong this page.

+1

đối với tôi làm ví dụ mới bắt đầu không đủ rõ ràng –

+0

tôi đã bị mất trong các ví dụ – achabahe

23

Trong gắn thẻ ASN.1, trên thực tế, phục vụ hai mục đích: nhập và đặt tên. Kiểu gõ có nghĩa là nó cho một bộ giải mã loại dữ liệu nào (là một chuỗi, số nguyên, boolean, tập hợp, v.v.), đặt tên có nghĩa là nếu có nhiều trường cùng loại và một số (hoặc tất cả chúng) là tùy chọn, nó cho bộ giải mã biết giá trị của trường nào.

Nếu bạn so sánh ASN.1 để, chúng ta hãy nói, JSON, và bạn nhìn vào các dữ liệu JSON sau:

"Image": { 
    "Width": 800, 
    "Height": 600, 
    "Title": "View from 15th Floor" 
} 

Bạn sẽ nhận thấy rằng trong JSON mọi lĩnh vực luôn luôn rõ ràng tên ("Hình ảnh" , "Chiều rộng", "Chiều cao", "Tiêu đề") và được nhập rõ ràng hoặc ngầm định ("Tiêu đề" là một chuỗi, vì giá trị của nó được bao quanh bởi dấu ngoặc kép, "Chiều rộng" là số nguyên, vì nó không có dấu ngoặc kép, chỉ chữ số , nó không phải là "null", "true" hoặc "false" và không có dấu chấm thập phân).

Trong ASN.1 mảnh dữ liệu này sẽ là:

Image ::= SEQUENCE { 
    Width INTEGER, 
    Height INTEGER, 
    Title UTF8String 
} 

này sẽ làm việc mà không cần bất kỳ gắn thẻ đặc biệt, ở đây chỉ các thẻ phổ biến được yêu cầu. Universal tags không đặt tên dữ liệu, chúng chỉ cần nhập dữ liệu, do đó, bộ giải mã biết rằng hai giá trị đầu tiên là số nguyên và giá trị cuối cùng là một chuỗi. Đó là số nguyên đầu tiên là chiều rộng và thứ hai là chiều cao không cần phải được mã hóa trong dòng byte, nó được xác định theo thứ tự của chúng (chuỗi có một trật tự cố định, bộ không. Trên trang bạn gọi bộ là đang được sử dụng).

Bây giờ thay đổi giản đồ như sau:

Image ::= SEQUENCE { 
    Width INTEGER OPTIONAL, 
    Height INTEGER OPTIONAL, 
    Title UTF8String 
} 

Được rồi, bây giờ chúng tôi có một vấn đề. Giả sử rằng các dữ liệu sau đây được nhận:

INTEGER(750), UTF8String("A funny kitten") 

750 là gì? Chiều rộng hoặc chiều cao? Có thể là Chiều rộng (và Chiều cao bị thiếu) hoặc có thể là Chiều cao (và Chiều rộng bị thiếu), cả hai sẽ trông giống như một luồng nhị phân. Trong JSON sẽ rõ ràng khi mọi phần dữ liệu được đặt tên, trong ASN.1 thì không. Bây giờ một loại một mình là không đủ, bây giờ chúng ta cũng cần một cái tên. Đó là nơi các thẻ không phổ dụng tham gia trò chơi. Thay đổi nó thành:

Image ::= SEQUENCE { 
    Width [0] INTEGER OPTIONAL, 
    Height [1] INTEGER OPTIONAL, 
    Title UTF8String 
} 

Và nếu bạn nhận được dữ liệu sau:

[1]INTEGER(750), UTF8String("A funny kitten") 

Bạn biết rằng 750 là Chiều cao và không phải là Width (đơn giản là không Width). Ở đây bạn khai báo một thẻ mới (trong trường hợp đó một ngữ cảnh cụ thể) phục vụ hai mục đích: Nó báo cho bộ giải mã rằng đây là một giá trị số nguyên (nhập) và nó cho biết giá trị số nguyên nào (đặt tên).

Nhưng sự khác biệt giữa gắn thẻ rõ ràng và rõ ràng là gì? Sự khác biệt là gắn thẻ ngầm chỉ đặt tên cho dữ liệu, bộ giải mã cần phải biết loại ngầm cho tên đó, trong khi tên gắn thẻ rõ ràng và rõ ràng nhập dữ liệu.

Nếu gắn thẻ là rõ ràng, dữ liệu sẽ được gửi dưới dạng:

[1]INTEGER(xxx), UTF8String(yyy) 

vì vậy ngay cả nếu một bộ giải mã không có ý kiến ​​cho rằng [1] có nghĩa là chiều cao, nó biết rằng các byte "xxx" đang được phân tích cú pháp/được hiểu là giá trị số nguyên. Một lợi thế quan trọng khác của gắn thẻ rõ ràng là loại có thể được thay đổi trong tương lai mà không thay đổi thẻ. Ví dụ.

Length ::= [0] INTEGER 

có thể được thay đổi để

Length ::= [0] CHOICE { 
    integer INTEGER, 
    real REAL 
} 

Tag [0] vẫn có nghĩa là chiều dài, nhưng bây giờ thời gian có thể là một số nguyên hoặc một giá trị dấu chấm động. Vì loại được mã hóa một cách rõ ràng, bộ giải mã sẽ luôn biết cách giải mã chính xác giá trị và thay đổi này do đó tương thích về phía trước và ngược (ít nhất ở mức bộ giải mã, không nhất thiết phải tương thích ngược ở cấp ứng dụng).

Nếu gắn thẻ là tiềm ẩn, dữ liệu sẽ được gửi dưới dạng:

[1](xxx), UTF8String(yyy) 

Một bộ giải mã mà không biết những gì [1] là, sẽ không biết loại "xxx" và do đó không thể phân tích cú pháp/giải thích dữ liệu đó một cách chính xác. Không giống như JSON, các giá trị trong ASN.1 chỉ là các byte. Vì vậy, "xxx" có thể là một, hai, ba hoặc có thể bốn byte và cách giải mã các byte đó phụ thuộc vào loại dữ liệu của chúng, không được cung cấp trong luồng dữ liệu. Thay đổi kiểu [1] cũng sẽ phá vỡ bộ giải mã hiện tại.

Được rồi, nhưng tại sao mọi người lại sử dụng gắn thẻ ngầm? Không phải lúc nào cũng tốt hơn để luôn sử dụng gắn thẻ rõ ràng? Với gắn thẻ rõ ràng, loại cũng phải được mã hóa trong luồng dữ liệu và điều này sẽ yêu cầu hai byte bổ sung cho mỗi thẻ. Đối với truyền dữ liệu có chứa hàng nghìn thẻ (và thậm chí là hàng triệu) và có thể mỗi byte đơn (kết nối rất chậm, gói nhỏ, mất gói tin cao, thiết bị xử lý rất yếu) và cả hai bên đều biết tất cả các thẻ tùy chỉnh, tại sao lại lãng phí băng thông , bộ nhớ, lưu trữ và/hoặc thời gian xử lý để mã hóa, truyền và giải mã thông tin loại không cần thiết? Hãy nhớ rằng ASN.1 là một tiêu chuẩn khá cũ và nó được dự định để đạt được một đại diện rất nhỏ gọn của dữ liệu tại một thời điểm băng thông mạng là rất tốn kém và xử lý vài trăm lần chậm hơn so với ngày hôm nay. Nếu bạn xem xét tất cả các chuyển dữ liệu XML và JSON của ngày hôm nay, có vẻ như vô lý để thậm chí nghĩ đến việc tiết kiệm hai byte cho mỗi thẻ.

+0

Tham chiếu: https://osqa-ask.wireshark.org/questions/8277/difference-between-implicit-and-explicit -tags-asn1. Ở đây, a) A :: = INTEGER với giá trị 5 được mã hóa dưới dạng hex 02 01 05, b) B :: = [2] IMPLICIT INTEGER với giá trị 5 được mã hóa dưới dạng hex 82 01 05 và c) C :: = [2 ] EXPLICIT INTEGER với giá trị 5 được mã hóa dưới dạng hex A2 03 02 01 05. Có ai vui lòng giải thích trường hợp b và trường hợp c! – AVA

+0

@AVA Nếu bạn có câu hỏi, tại sao bạn không đặt câu hỏi? Tại sao bạn đặt câu hỏi của mình vào nhận xét? SO là tất cả về việc đặt câu hỏi, vì vậy hãy tìm câu hỏi và đặt câu hỏi. – Mecki

Các vấn đề liên quan