DEV Community

cadguide.tools
cadguide.tools

Posted on

Parsing AutoCAD DWG Binary Headers 100% Client-Side in JavaScript (Zero Cloud Leaks)

The Problem with Traditional DWG Converters

If you work in architectural drafting, mechanical engineering, or manufacturing, you have encountered this dreaded error at least once:

Drawing file is not valid.
Enter fullscreen mode Exit fullscreen mode

In 90% of cases, the drawing is not corrupted at all. Instead, a vendor or contractor saved the drawing in a newer AutoCAD version (for example, AutoCAD 2024 using the AC1032 format), while the recipient is running an older license (such as AutoCAD 2016 which only supports up to AC1027).

To solve this, designers typically turn to random web-based "free DWG viewers" or "online converters". But here lies a major security hazard: uploading proprietary intellectual property (IP), proprietary tooling designs, and confidential floor plans to untrusted third-party servers.

We wanted to solve this by inspecting the binary format 100% client-side inside the browser sandbox in under 5 milliseconds, without a single byte ever touching a remote server.

Here is the technical breakdown of how AutoCAD DWG binary headers work and how we built our zero-upload inspector at CADGuide.tools DWG Version Checker.


Reverse Engineering the First 6 Bytes of a DWG

The AutoCAD DWG format is a proprietary binary stream maintained by Autodesk. While parsing the full B-Rep solids or entity trees requires heavy C++ SDKs (like Open Design Alliance Teigha / Drawings SDK), identifying the format version only requires the first 6 bytes of the file.

Autodesk stores a standardized ASCII magic string at byte offset 0x00 through 0x05:

Offset (Hex): 00 01 02 03 04 05
ASCII String: A  C  1  0  3  2
Enter fullscreen mode Exit fullscreen mode

Every major AutoCAD format generation has a unique ASCII identifier:

Magic Header Internal Code AutoCAD Release Generation Release Year
AC1032 2018 AutoCAD 2018, 2019, 2020, 2021, 2022, 2023, 2024, 2025, 2026 2018
AC1027 2013 AutoCAD 2013, 2014, 2015, 2016, 2017 2013
AC1024 2010 AutoCAD 2010, 2011, 2012 2010
AC1021 2007 AutoCAD 2007, 2008, 2009 2007
AC1018 2004 AutoCAD 2004, 2005, 2006 2004
AC1015 2000 AutoCAD 2000, 2000i, 2002 2000
AC1014 R14 AutoCAD Release 14 1997
AC1012 R13 AutoCAD Release 13 1994
AC1009 R11/R12 AutoCAD Release 11 & 12 1990

Notice an interesting pattern: Autodesk does not update the file format every year. For instance, AutoCAD 2018 through 2026 all share the exact same AC1032 format. That means a DWG saved from AutoCAD 2026 can be natively opened in AutoCAD 2018 without any conversion.


The Client-Side Implementation

Instead of reading a 500MB drawing into browser memory with FileReader.readAsArrayBuffer(file), we use HTML5 Blob.prototype.slice(). This tells the operating system kernel to slice only the header chunk:

export interface DwgInspectionResult {
  valid: boolean;
  headerCode?: string;
  versionTitle?: string;
  releaseYear?: number;
  compatibilityNote?: string;
  error?: string;
}

const DWG_MAGIC_MAP: Record<string, { title: string; year: number; note: string }> = {
  'AC1032': { title: 'AutoCAD 2018 - 2026', year: 2018, note: 'Native format for AutoCAD 2018 through 2026' },
  'AC1027': { title: 'AutoCAD 2013 - 2017', year: 2013, note: 'Requires AutoCAD 2013 or newer' },
  'AC1024': { title: 'AutoCAD 2010 - 2012', year: 2010, note: 'Legacy Unicode format' },
  'AC1021': { title: 'AutoCAD 2007 - 2009', year: 2007, note: 'Legacy format' },
  'AC1018': { title: 'AutoCAD 2004 - 2006', year: 2004, note: 'Pre-Unicode format' },
  'AC1015': { title: 'AutoCAD 2000 - 2002', year: 2000, note: 'Classic 2000 format' }
};

export async function inspectDwgFile(file: File): Promise<DwgInspectionResult> {
  if (!file || file.size < 6) {
    return { valid: false, error: 'File is smaller than the minimum 6-byte header threshold.' };
  }

  // 1. Slice ONLY the first 6 bytes from disk stream
  const headerSlice = file.slice(0, 6);
  const buffer = await headerSlice.arrayBuffer();
  const bytes = new Uint8Array(buffer);

  // 2. Decode ASCII magic header
  let magic = '';
  for (let i = 0; i < 6; i++) {
    magic += String.fromCharCode(bytes[i]);
  }

  // 3. Match against known definitions
  const match = DWG_MAGIC_MAP[magic];
  if (!match) {
    return {
      valid: false,
      headerCode: magic,
      error: `Unrecognized magic header: "${magic}". This file may be an encrypted DWG or a corrupted export.`
    };
  }

  return {
    valid: true,
    headerCode: magic,
    versionTitle: match.title,
    releaseYear: match.year,
    compatibilityNote: match.note
  };
}
Enter fullscreen mode Exit fullscreen mode

Why This Is Fast and Secure

  1. Zero Memory Pressure: Even if a user drops a 2GB campus layout drawing, only 6 bytes are mapped into memory.
  2. True Air-Gapped Operation: Because all processing happens inside the ArrayBuffer slice, you can disconnect your Wi-Fi or run the page in an air-gapped defense contractor laptop, and it works identically.
  3. Instant Latency: Execution finishes in < 2ms, completely bypassing server round-trips.

Try It Live & Open Source

We published this logic as a standalone NPM package:

If you manage a design team or run CAD pipelines, feel free to integrate the snippet into your pre-flight asset ingestion checks!

Top comments (0)