Counter Strike : Global Offensive Source Code
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

107 lines
5.1 KiB

  1. A Fast Method for Identifying Plain Text Files
  2. ==============================================
  3. Introduction
  4. ------------
  5. Given a file coming from an unknown source, it is sometimes desirable
  6. to find out whether the format of that file is plain text. Although
  7. this may appear like a simple task, a fully accurate detection of the
  8. file type requires heavy-duty semantic analysis on the file contents.
  9. It is, however, possible to obtain satisfactory results by employing
  10. various heuristics.
  11. Previous versions of PKZip and other zip-compatible compression tools
  12. were using a crude detection scheme: if more than 80% (4/5) of the bytes
  13. found in a certain buffer are within the range [7..127], the file is
  14. labeled as plain text, otherwise it is labeled as binary. A prominent
  15. limitation of this scheme is the restriction to Latin-based alphabets.
  16. Other alphabets, like Greek, Cyrillic or Asian, make extensive use of
  17. the bytes within the range [128..255], and texts using these alphabets
  18. are most often misidentified by this scheme; in other words, the rate
  19. of false negatives is sometimes too high, which means that the recall
  20. is low. Another weakness of this scheme is a reduced precision, due to
  21. the false positives that may occur when binary files containing large
  22. amounts of textual characters are misidentified as plain text.
  23. In this article we propose a new, simple detection scheme that features
  24. a much increased precision and a near-100% recall. This scheme is
  25. designed to work on ASCII, Unicode and other ASCII-derived alphabets,
  26. and it handles single-byte encodings (ISO-8859, MacRoman, KOI8, etc.)
  27. and variable-sized encodings (ISO-2022, UTF-8, etc.). Wider encodings
  28. (UCS-2/UTF-16 and UCS-4/UTF-32) are not handled, however.
  29. The Algorithm
  30. -------------
  31. The algorithm works by dividing the set of bytecodes [0..255] into three
  32. categories:
  33. - The white list of textual bytecodes:
  34. 9 (TAB), 10 (LF), 13 (CR), 32 (SPACE) to 255.
  35. - The gray list of tolerated bytecodes:
  36. 7 (BEL), 8 (BS), 11 (VT), 12 (FF), 26 (SUB), 27 (ESC).
  37. - The black list of undesired, non-textual bytecodes:
  38. 0 (NUL) to 6, 14 to 31.
  39. If a file contains at least one byte that belongs to the white list and
  40. no byte that belongs to the black list, then the file is categorized as
  41. plain text; otherwise, it is categorized as binary. (The boundary case,
  42. when the file is empty, automatically falls into the latter category.)
  43. Rationale
  44. ---------
  45. The idea behind this algorithm relies on two observations.
  46. The first observation is that, although the full range of 7-bit codes
  47. [0..127] is properly specified by the ASCII standard, most control
  48. characters in the range [0..31] are not used in practice. The only
  49. widely-used, almost universally-portable control codes are 9 (TAB),
  50. 10 (LF) and 13 (CR). There are a few more control codes that are
  51. recognized on a reduced range of platforms and text viewers/editors:
  52. 7 (BEL), 8 (BS), 11 (VT), 12 (FF), 26 (SUB) and 27 (ESC); but these
  53. codes are rarely (if ever) used alone, without being accompanied by
  54. some printable text. Even the newer, portable text formats such as
  55. XML avoid using control characters outside the list mentioned here.
  56. The second observation is that most of the binary files tend to contain
  57. control characters, especially 0 (NUL). Even though the older text
  58. detection schemes observe the presence of non-ASCII codes from the range
  59. [128..255], the precision rarely has to suffer if this upper range is
  60. labeled as textual, because the files that are genuinely binary tend to
  61. contain both control characters and codes from the upper range. On the
  62. other hand, the upper range needs to be labeled as textual, because it
  63. is used by virtually all ASCII extensions. In particular, this range is
  64. used for encoding non-Latin scripts.
  65. Since there is no counting involved, other than simply observing the
  66. presence or the absence of some byte values, the algorithm produces
  67. consistent results, regardless what alphabet encoding is being used.
  68. (If counting were involved, it could be possible to obtain different
  69. results on a text encoded, say, using ISO-8859-16 versus UTF-8.)
  70. There is an extra category of plain text files that are "polluted" with
  71. one or more black-listed codes, either by mistake or by peculiar design
  72. considerations. In such cases, a scheme that tolerates a small fraction
  73. of black-listed codes would provide an increased recall (i.e. more true
  74. positives). This, however, incurs a reduced precision overall, since
  75. false positives are more likely to appear in binary files that contain
  76. large chunks of textual data. Furthermore, "polluted" plain text should
  77. be regarded as binary by general-purpose text detection schemes, because
  78. general-purpose text processing algorithms might not be applicable.
  79. Under this premise, it is safe to say that our detection method provides
  80. a near-100% recall.
  81. Experiments have been run on many files coming from various platforms
  82. and applications. We tried plain text files, system logs, source code,
  83. formatted office documents, compiled object code, etc. The results
  84. confirm the optimistic assumptions about the capabilities of this
  85. algorithm.
  86. --
  87. Cosmin Truta
  88. Last updated: 2006-May-28