UNPKG

mmsi-country-lookup

Version:

A library to extract country information from MMSI (Maritime Mobile Service Identity) numbers with full ITU-R M.585-9 compliance

130 lines (113 loc) 3.7 kB
const midsData = require("./mids.json"); /** * Extract MID (Maritime Identification Digit) from MMSI * @param {string|number} mmsi - The MMSI number * @returns {string|null} - The 3-digit MID or null if invalid */ function getMIDFromMMSI(mmsi) { if (!mmsi) return null; const mmsiStr = mmsi.toString().trim(); if (mmsiStr.length !== 9 || !/^\d{9}$/.test(mmsiStr)) { return null; } // Special cases where MID is not in first 3 digits: // - Coast stations (00MIDXXXX): MID is digits 3-5 // - SAR aircraft (111MIDXXX): MID is digits 4-6 // - AIS aids (99MIDXXXX): MID is digits 3-5 if (mmsiStr.startsWith("00")) { return mmsiStr.substring(2, 5); // 00MIDXXXX → extract MID } else if (mmsiStr.startsWith("111")) { return mmsiStr.substring(3, 6); // 111MIDXXX → extract MID } else if (mmsiStr.startsWith("99")) { return mmsiStr.substring(2, 5); // 99MIDXXXX → extract MID } // Default: first 3 digits for ships (MIDXXXXXX) return mmsiStr.substring(0, 3); } /** * Check if MMSI is valid based on ITU-R M.585-9 * @param {string|number} mmsi - The MMSI number * @returns {boolean} - True if valid */ function isValidMMSI(mmsi) { if (!mmsi) return false; const mmsiStr = mmsi.toString().trim(); if (mmsiStr.length !== 9 || !/^\d{9}$/.test(mmsiStr)) { return false; } const firstDigit = parseInt(mmsiStr[0]); // Validity rules per M.585-9: // 1. Ships: 2-7 (MIDXXXXXX) // 2. Coast stations: 00MIDXXXX // 3. SAR aircraft: 111MIDXXX // 4. AIS aids: 99MIDXXXX // 5. Craft associated with parent ship: 98MIDXXXX // 6. Handheld VHF: 8MIDXXXXX // 7. Special devices (AIS-SART, EPIRB-AIS, etc.): 9702XXXXX, 9722XXXXX, 9742XXXXX return ( (firstDigit >= 2 && firstDigit <= 7) || // Ships mmsiStr.startsWith("00") || // Coast stations mmsiStr.startsWith("111") || // SAR aircraft mmsiStr.startsWith("99") || // AIS aids mmsiStr.startsWith("98") || // Craft associated with parent ship mmsiStr.startsWith("8") || // Handheld VHF /^97[024]\d{6}$/.test(mmsiStr) // AIS-SART (970), MOB (972), EPIRB-AIS (974) ); } /** * Get country information from MMSI * @param {string|number} mmsi - The MMSI number * @returns {object} - Country information object */ function getCountryFromMMSI(mmsi) { const result = { mmsi: mmsi ? mmsi.toString() : "", mid: null, alpha2: null, alpha3: null, country: null, valid: false, type: null, // Added to indicate MMSI type }; if (!isValidMMSI(mmsi)) { return result; } const mmsiStr = mmsi.toString(); const mid = getMIDFromMMSI(mmsiStr); // Determine MMSI type if (mmsiStr.startsWith("00")) { result.type = "coast_station"; } else if (mmsiStr.startsWith("111")) { result.type = "sar_aircraft"; } else if (mmsiStr.startsWith("99")) { result.type = "ais_aid_to_navigation"; } else if (mmsiStr.startsWith("98")) { result.type = "craft_associated_with_parent_ship"; } else if (mmsiStr.startsWith("8")) { result.type = "handheld_vhf"; } else if (/^97[024]/.test(mmsiStr)) { result.type = "emergency_device"; } else { result.type = "ship"; } // For emergency devices (AIS-SART, MOB, EPIRB-AIS), no country association if (result.type === "emergency_device") { result.valid = true; return result; } // For other types, lookup MID in database const countryData = midsData[mid]; if (countryData) { result.mid = mid; result.alpha2 = countryData[0]; result.alpha3 = countryData[1]; result.country = countryData[3]; result.valid = true; } return result; } module.exports = { getCountryFromMMSI, isValidMMSI, getMIDFromMMSI, };