Flutter mobile_scanner: Proper way to handle/validate check digit for UPC/EAN barcodes?

1. I am using the mobile_scanner package in Flutter to scan different types of barcodes (UPC-A, UPC-E, EAN-13, EAN-8, Code128, etc.).I am using the validation?

2. Is there any Dart/Flutter package for proper barcode parsing and validation (especially UPC/EAN)?

3. What is the recommended approach in production apps for handling check digits?

I want to avoid manual string manipulation if there is a more reliable or standard approach.

The scanner returns the raw value including the check digit, but I need more control over how the barcode value is processed.

Requirement:

- Optionally remove the check digit

- Normalize UPC/EAN values (e.g., convert EAN-13 starting with ‘0’ to UPC-A)

- Ideally validate the check digit instead of blindly trimming it

Currently, I am handling this manually with the following logic:

String? normalizeBarcodeValue(Barcode barcode) {
    final raw = barcode.rawValue;
    if (raw == null) {
      return null;
    }

    switch (barcode.format) {
      // UPC/EAN family: keep numeric only and drop check digit where required.
      case BarcodeFormat.upcA:
      case BarcodeFormat.upcE:
        var normalized = raw.replaceAll(RegExp(r'\D'), '');
        if (normalized.length == 12) {
          normalized = normalized.substring(0, 11);
        }
        return normalized;

      case BarcodeFormat.ean13:
        var normalized = raw.replaceAll(RegExp(r'\D'), '');
        if (normalized.length == 13 && normalized.startsWith('0')) {
          normalized = normalized.substring(1);
        }
        if (normalized.length == 12) {
          normalized = normalized.substring(0, 11);
        }
        return normalized;

      case BarcodeFormat.ean8:
        return raw.replaceAll(RegExp(r'\D'), '');

      // 1D/2D symbologies supported by mobile_scanner.
      case BarcodeFormat.itf14:
      case BarcodeFormat.code39:
      case BarcodeFormat.code93:
      case BarcodeFormat.code128:
      case BarcodeFormat.codabar:
      case BarcodeFormat.pdf417:
      case BarcodeFormat.dataMatrix:
      case BarcodeFormat.qrCode:
      case BarcodeFormat.aztec:
      case BarcodeFormat.unknown:
        return raw.trim();

      // Keep default trimming for any future formats.
      default:
        return raw.trim();
    }
  }

This approach works, but it feels like a workaround rather than a proper solution.

Is it expected that barcode normalization (like check digit removal/validation) should always be handled at application level in Flutter?

Dumb question: why doesn’t the scanner process the check digit for you? If you’re using the camera on the device, it probably won’t, but most hardware scanners handle the check digit, and won’t pass barcodes that fail the check digit.

Actually, when we are using the IR scanner of those devices then we have an app where we can do all those configuration to check/ uncheck the “Return Check Digit” option but that is not available when we are using the camera of the same device.