Close menu

ISO 6346


Source: http://en.wikipedia.org/wiki/ISO_6346
Updated: 2017-07-28T04:41Z
ISO 6346
Freight containers -- Coding, identification and marking
Latest version3
6346:1995
Preview version1984
OrganizationInternational Organization for Standardization
AbbreviationISO 6346:1995


ISO-code and dimension/load table at several newly washed containers

ISO 6346 is an international standard covering the coding, identification and marking of intermodal (shipping) containers used within containerized intermodal freight transport[1]. The standard establishes a visual identification system for every container that includes a unique serial number (with check digit), the owner, a country code, a size, type and equipment category as well as any operational marks. The standard is managed by the International Container Bureau (BIC).

Identification System

Example of an ISO 6346 compliant container number:

Example of an ISO 6346 conform container number

BIC code on the end of a shipping container

Owner Code

The owner code consists of three capital letters of the Latin alphabet to indicate the owner or principal operator of the container. Such code needs to be registered at the Bureau International des Conteneurs in Paris to ensure uniqueness worldwide.

Equipment Category Identifier

The equipment category identifier consists of one of the following capital letters of the Latin alphabet:

  • U for all freight containers
  • J for detachable freight container-related equipment
  • Z for trailers and chassis

Under the ISO code, then, only U, J, and Z are in use. The reefer container is identified by means of the size type code.

Serial Number

The serial number consists of 6 numeric digits, assigned by the owner or operator, uniquely identifying the container within that owner/operator's fleet.

Check Digit

The check digit consists of one numeric digit providing a means of validating the recording and transmission accuracies of the owner code and serial number.

Conversion Algorithm

To compute the check digit, the letters have to be converted to numbers. This is done in three steps:

Calculation Step 1

An equivalent numerical value is assigned to each letter of the alphabet, beginning with 10 for the letter A (11 and multiples thereof are omitted):

ABCDEFGHIJKLM
10121314151617181920212324
NOPQRSTUVWXYZ
25262728293031323435363738

The individual digits of the serial number keep their numeric value.

Calculation Step 2

Each of the numbers calculated in step 1 is multiplied by 2position, where position is the exponent to base 2. Position starts at 0, from left to right.

The following table shows the multiplication factors:

1. nbr2. nbr3. nbr4. nbr5. nbr6. nbr7. nbr8. nbr9. nbr10. nbr
20212223242526272829
1248163264128256512
Calculation Step 3
  1. Sum up all results of Step 2
  2. Divide them by 11
  3. Round the result down to zero i.e. make the result a whole number (integer)
  4. Multiply the integer value by 11
  5. Subtract result of (iv) from result of (i): This is the check digit.

If the final difference is 10, then the check digit becomes 0. To ensure that this does not happen, the standard recommends that serial numbers should not be used which produce a final difference of 10; however, there are containers in the market which do not follow this recommendation, so handling this case has to be included if a check digit calculator is programmed.

Notice that step (ii) to (v) is a calculation of the remainder found after division of (i) by 11. Most programming languages have a modulo operator for this. Attention should be paid on how it is working in the language chosen; i. e. if it is giving back the decimal rest or the integer rest in order to get proper results. 11 is used as divisor because a container number has 11 letters and digits in total. In step 1 the numbers 11, 22 and 33 are left out as they are multiples of the divisor.

Example
CSQU305438Calc.
13302832305438
×1248163264128256512
136011225648032051276840966185 [a]
b) Division by 11:562.272...
c) Erase decimal digits:562
d) Multiply by 11:6182
a) minus d) = Check Digit:3
Code Samples

The following are the algorithm in various programming languages:


Code Sample (C#)
        public int Calculate(string equipmentNumber)        {            //Details on algorithm can be found here https://en.wikipedia.org/wiki/ISO_6346#Check_Digit            //Step 1             var numerics = equipmentNumber.Select(c => "0123456789A?BCDEFGHIJK?LMNOPQRSTU?VWXYZ".IndexOf(c));            //Step 2, Step 3(i)            var totalStringValue = numerics.Select((n, index) => Math.Pow(2, index) * n).Sum(x => (int) x);            //Step 3(ii,iii,iv, v)            var retval = totalStringValue % 11;            return retval == 10 ? 0 : retval;        }
Code Sample (Matlab)

Below is a code Snippet implementing the above algorithm in MATLAB validating string "cid":

%% Step 1 char2num = [10 12 13 14 15 16 17 18 19 20 21 23 24 25 26 27 28 29 30 31 32 34 35 36 37 38]; msk = logical([1 1 1 1 0 0 0 0 0 0 0]);  % mask separating digits from numberscid( msk) = char2num(cid( msk)-'A'+1);   % letters to numbers conversioncid(~msk) =          cid(~msk)-'1'+1;    % digit characters to numbers conversionvec = double(cid);%% Step 2num  = sum(vec(1:10).* 2.^(0:9));%% Step 3check_digit = mod(mod(num,11),10);valid = (check_digit==vec(11));
Code Sample (DELPHİ or pascal)
function knt(x: String): Boolean;vardizi:Array ['A'..'Z'] of Integer;acc,ax:Extended;i,remx,s:integer;z:Boolean;beginz:=False;dizi['A']:=10; dizi['B']:=12; dizi['C']:=13; dizi['D']:=14; dizi['E']:=15; dizi['F']:=16;dizi['G']:=17; dizi['H']:=18; dizi['I']:=19; dizi['J']:=20; dizi['K']:=21; dizi['L']:=23;dizi['M']:=24; dizi['N']:=25; dizi['O']:=26; dizi['P']:=27; dizi['Q']:=28; dizi['R']:=29;dizi['S']:=30; dizi['T']:=31; dizi['U']:=32; dizi['V']:=34; dizi['W']:=35; dizi['X']:=36;dizi['Y']:=37; dizi['Z']:=38;acc:=0;s:=0;for i :=1  to 10  dobegins:=s*2;if s<1 then s:=1;  if i<5 then    ax:=(dizi[x[i]]*s)  else    ax:=(StrToInt(x[i])*s);acc:=acc+ax;end;remx:=(Floor(acc) mod 11) mod 10;if (Length(x)=11) and (remx=StrToInt(x[11])) thenz:=True;Result:= z;end;
Code Sample (Visual Basic)

Below is the Visual Basic (VBA) code to create a custom "ISO6346Check" function in Microsoft Excel (Alt + F11) that returns the correct check digit:

Function ISO6346Check(k As String) ' Calculates the ISO Shipping Container Check DigitDim i%, s&Application.VolatileFor i = 1 To 10s = s + IIf(i < 5, Fix(11 * (Asc(Mid(k, i)) - 56) / 10) + 1, Asc(Mid(k, i)) - 48) * 2 ^ (i - 1)Next iISO6346Check = (s - Fix(s / 11) * 11) Mod 10End Function
Code Sample (Python)

Below is Python (2.7) code to validate the string "cid":

>>> cid = 'CSQU3054383'>>> first10 = cid[0:-1]>>> check = cid[-1]>>> char2num = {...     '0': 0, '1': 1, '2': 2, '3': 3, '4': 4, '5': 5, '6': 6, '7': 7, '8': 8,...     '9': 9, 'A': 10, 'B': 12, 'C': 13, 'D': 14, 'E': 15, 'F': 16, 'G': 17,...     'H': 18, 'I': 19, 'J': 20, 'K': 21, 'L': 23, 'M': 24, 'N': 25, 'O': 26,...     'P': 27, 'Q': 28, 'R': 29, 'S': 30, 'T': 31, 'U': 32, 'V': 34, 'W': 35,...     'X': 36, 'Y': 37, 'Z': 38,... }>>> total = sum(char2num[c] * 2**x for x, c in enumerate(first10))>>> (total % 11) % 10 == char2num[check]True
Code Sample (Javascript)

Below is the Javascript code to create a custom "ISO6346Check":

function ISO6346Check(con) {    if (!con || con == "" || con.length != 11) { return false; }    con = con.toUpperCase();    var re = /^[A-Z]{4}\d{7}/;    if (re.test(con)) {        var sum = 0;        for (i = 0; i < 10; i++) {            var n = con.substr(i, 1);            if (i < 4) {                n = "0123456789A?BCDEFGHIJK?LMNOPQRSTU?VWXYZ".indexOf(con.substr(i, 1));            }            n *= Math.pow(2, i); //2的i次方            sum += n;        }        if (con.substr(0, 4) == "HLCU") {            sum -= 2;        }        sum %= 11;        sum %= 10; //余数为10的取0A        return sum == con.substr(10);    } else {        return false; //不匹配正则表达式       }}
Code Sample (Excel)

Below is an Excel Formula to validate container number in Cell A1[citation needed]

=IF(LEN(A1)=11,IF((MID(A1,11,1)*1)=(1*SUBSTITUTE((IF(MID(A1,1,1)="A",10,IF(MID(A1,1,1)="B",12,IF(MID(A1,1,1)="C",13,IF(MID(A1,1,1)="D",14,IF(MID(A1,1,1)="E",15,IF(MID(A1,1,1)="F",16,IF(MID(A1,1,1)="G",17,IF(MID(A1,1,1)="H",18,IF(MID(A1,1,1)="I",19,IF(MID(A1,1,1)="J",20,IF(MID(A1,1,1)="K",21,IF(MID(A1,1,1)="L",23,IF(MID(A1,1,1)="M",24,IF(MID(A1,1,1)="N",25,IF(MID(A1,1,1)="O",26,IF(MID(A1,1,1)="P",27,IF(MID(A1,1,1)="Q",28,IF(MID(A1,1,1)="R",29,IF(MID(A1,1,1)="S",30,IF(MID(A1,1,1)="T",31,IF(MID(A1,1,1)="U",32,IF(MID(A1,1,1)="V",34,IF(MID(A1,1,1)="W",35,IF(MID(A1,1,1)="X",36,IF(MID(A1,1,1)="Y",37,IF(MID(A1,1,1)="Z",38,FALSE)))))))))))))))))))))))))))+(IF(MID(A1,2,1)="A",10,IF(MID(A1,2,1)="B",12,IF(MID(A1,2,1)="C",13,IF(MID(A1,2,1)="D",14,IF(MID(A1,2,1)="E",15,IF(MID(A1,2,1)="F",16,IF(MID(A1,2,1)="G",17,IF(MID(A1,2,1)="H",18,IF(MID(A1,2,1)="I",19,IF(MID(A1,2,1)="J",20,IF(MID(A1,2,1)="K",21,IF(MID(A1,2,1)="L",23,IF(MID(A1,2,1)="M",24,IF(MID(A1,2,1)="N",25,IF(MID(A1,2,1)="O",26,IF(MID(A1,2,1)="P",27,IF(MID(A1,2,1)="Q",28,IF(MID(A1,2,1)="R",29,IF(MID(A1,2,1)="S",30,IF(MID(A1,2,1)="T",31,IF(MID(A1,2,1)="U",32,IF(MID(A1,2,1)="V",34,IF(MID(A1,2,1)="W",35,IF(MID(A1,2,1)="X",36,IF(MID(A1,2,1)="Y",37,IF(MID(A1,2,1)="Z",38,FALSE))))))))))))))))))))))))))*2)+(IF(MID(A1,3,1)="A",10,IF(MID(A1,3,1)="B",12,IF(MID(A1,3,1)="C",13,IF(MID(A1,3,1)="D",14,IF(MID(A1,3,1)="E",15,IF(MID(A1,3,1)="F",16,IF(MID(A1,3,1)="G",17,IF(MID(A1,3,1)="H",18,IF(MID(A1,3,1)="I",19,IF(MID(A1,3,1)="J",20,IF(MID(A1,3,1)="K",21,IF(MID(A1,3,1)="L",23,IF(MID(A1,3,1)="M",24,IF(MID(A1,3,1)="N",25,IF(MID(A1,3,1)="O",26,IF(MID(A1,3,1)="P",27,IF(MID(A1,3,1)="Q",28,IF(MID(A1,3,1)="R",29,IF(MID(A1,3,1)="S",30,IF(MID(A1,3,1)="T",31,IF(MID(A1,3,1)="U",32,IF(MID(A1,3,1)="V",34,IF(MID(A1,3,1)="W",35,IF(MID(A1,3,1)="X",36,IF(MID(A1,3,1)="Y",37,IF(MID(A1,3,1)="Z",38,FALSE))))))))))))))))))))))))))*4)+(IF(MID(A1,4,1)="A",10,IF(MID(A1,4,1)="B",12,IF(MID(A1,4,1)="C",13,IF(MID(A1,4,1)="D",14,IF(MID(A1,4,1)="E",15,IF(MID(A1,4,1)="F",16,IF(MID(A1,4,1)="G",17,IF(MID(A1,4,1)="H",18,IF(MID(A1,4,1)="I",19,IF(MID(A1,4,1)="J",20,IF(MID(A1,4,1)="K",21,IF(MID(A1,4,1)="L",23,IF(MID(A1,4,1)="M",24,IF(MID(A1,4,1)="N",25,IF(MID(A1,4,1)="O",26,IF(MID(A1,4,1)="P",27,IF(MID(A1,4,1)="Q",28,IF(MID(A1,4,1)="R",29,IF(MID(A1,4,1)="S",30,IF(MID(A1,4,1)="T",31,IF(MID(A1,4,1)="U",32,IF(MID(A1,4,1)="V",34,IF(MID(A1,4,1)="W",35,IF(MID(A1,4,1)="X",36,IF(MID(A1,4,1)="Y",37,IF(MID(A1,4,1)="Z",38,FALSE))))))))))))))))))))))))))*8)+(MID(A1,5,1)*16)+(MID(A1,6,1)*32)+(MID(A1,7,1)*64)+(MID(A1,8,1)*128)+(MID(A1,9,1)*256)+(MID(A1,10,1)*512)-11*ROUNDDOWN((((IF(MID(A1,1,1)="A",10,IF(MID(A1,1,1)="B",12,IF(MID(A1,1,1)="C",13,IF(MID(A1,1,1)="D",14,IF(MID(A1,1,1)="E",15,IF(MID(A1,1,1)="F",16,IF(MID(A1,1,1)="G",17,IF(MID(A1,1,1)="H",18,IF(MID(A1,1,1)="I",19,IF(MID(A1,1,1)="J",20,IF(MID(A1,1,1)="K",21,IF(MID(A1,1,1)="L",23,IF(MID(A1,1,1)="M",24,IF(MID(A1,1,1)="N",25,IF(MID(A1,1,1)="O",26,IF(MID(A1,1,1)="P",27,IF(MID(A1,1,1)="Q",28,IF(MID(A1,1,1)="R",29,IF(MID(A1,1,1)="S",30,IF(MID(A1,1,1)="T",31,IF(MID(A1,1,1)="U",32,IF(MID(A1,1,1)="V",34,IF(MID(A1,1,1)="W",35,IF(MID(A1,1,1)="X",36,IF(MID(A1,1,1)="Y",37,IF(MID(A1,1,1)="Z",38,FALSE)))))))))))))))))))))))))))+(IF(MID(A1,2,1)="A",10,IF(MID(A1,2,1)="B",12,IF(MID(A1,2,1)="C",13,IF(MID(A1,2,1)="D",14,IF(MID(A1,2,1)="E",15,IF(MID(A1,2,1)="F",16,IF(MID(A1,2,1)="G",17,IF(MID(A1,2,1)="H",18,IF(MID(A1,2,1)="I",19,IF(MID(A1,2,1)="J",20,IF(MID(A1,2,1)="K",21,IF(MID(A1,2,1)="L",23,IF(MID(A1,2,1)="M",24,IF(MID(A1,2,1)="N",25,IF(MID(A1,2,1)="O",26,IF(MID(A1,2,1)="P",27,IF(MID(A1,2,1)="Q",28,IF(MID(A1,2,1)="R",29,IF(MID(A1,2,1)="S",30,IF(MID(A1,2,1)="T",31,IF(MID(A1,2,1)="U",32,IF(MID(A1,2,1)="V",34,IF(MID(A1,2,1)="W",35,IF(MID(A1,2,1)="X",36,IF(MID(A1,2,1)="Y",37,IF(MID(A1,2,1)="Z",38,FALSE))))))))))))))))))))))))))*2)+(IF(MID(A1,3,1)="A",10,IF(MID(A1,3,1)="B",12,IF(MID(A1,3,1)="C",13,IF(MID(A1,3,1)="D",14,IF(MID(A1,3,1)="E",15,IF(MID(A1,3,1)="F",16,IF(MID(A1,3,1)="G",17,IF(MID(A1,3,1)="H",18,IF(MID(A1,3,1)="I",19,IF(MID(A1,3,1)="J",20,IF(MID(A1,3,1)="K",21,IF(MID(A1,3,1)="L",23,IF(MID(A1,3,1)="M",24,IF(MID(A1,3,1)="N",25,IF(MID(A1,3,1)="O",26,IF(MID(A1,3,1)="P",27,IF(MID(A1,3,1)="Q",28,IF(MID(A1,3,1)="R",29,IF(MID(A1,3,1)="S",30,IF(MID(A1,3,1)="T",31,IF(MID(A1,3,1)="U",32,IF(MID(A1,3,1)="V",34,IF(MID(A1,3,1)="W",35,IF(MID(A1,3,1)="X",36,IF(MID(A1,3,1)="Y",37,IF(MID(A1,3,1)="Z",38,FALSE))))))))))))))))))))))))))*4)+(IF(MID(A1,4,1)="A",10,IF(MID(A1,4,1)="B",12,IF(MID(A1,4,1)="C",13,IF(MID(A1,4,1)="D",14,IF(MID(A1,4,1)="E",15,IF(MID(A1,4,1)="F",16,IF(MID(A1,4,1)="G",17,IF(MID(A1,4,1)="H",18,IF(MID(A1,4,1)="I",19,IF(MID(A1,4,1)="J",20,IF(MID(A1,4,1)="K",21,IF(MID(A1,4,1)="L",23,IF(MID(A1,4,1)="M",24,IF(MID(A1,4,1)="N",25,IF(MID(A1,4,1)="O",26,IF(MID(A1,4,1)="P",27,IF(MID(A1,4,1)="Q",28,IF(MID(A1,4,1)="R",29,IF(MID(A1,4,1)="S",30,IF(MID(A1,4,1)="T",31,IF(MID(A1,4,1)="U",32,IF(MID(A1,4,1)="V",34,IF(MID(A1,4,1)="W",35,IF(MID(A1,4,1)="X",36,IF(MID(A1,4,1)="Y",37,IF(MID(A1,4,1)="Z",38,FALSE))))))))))))))))))))))))))*8)+(MID(A1,5,1)*16)+(MID(A1,6,1)*32)+(MID(A1,7,1)*64)+(MID(A1,8,1)*128)+(MID(A1,9,1)*256)+(MID(A1,10,1)*512))/11),0),10,0)),"VALID","INVALID"),"INVALID")

Below is a shorter Excel formula for the same function (container number in cell A1) (Warning, this code does not correctly account for a check digit result of "10"):

=IF(LEN(A1)=11,IF((MID(A1,11,1)*1)=MOD(IF(PROPER(MID(A1,1,1))="A",10,IF(AND(CODE(MID(A1,1,1))>65,CODE(MID(A1,1,1))<=75),CODE(MID(A1,1,1))-54,IF(AND(CODE(MID(A1,1,1))>75,CODE(MID(A1,1,1))<=85),CODE(MID(A1,1,1))-53,IF(AND(CODE(MID(A1,1,1))>85,CODE(MID(A1,1,1))<=90),CODE(MID(A1,1,1))-52,MID(A1,1,1)))))*1+IF(PROPER(MID(A1,2,1))="A",10,IF(AND(CODE(MID(A1,2,1))>65,CODE(MID(A1,2,1))<=75),CODE(MID(A1,2,1))-54,IF(AND(CODE(MID(A1,2,1))>75,CODE(MID(A1,2,1))<=85),CODE(MID(A1,2,1))-53,IF(AND(CODE(MID(A1,2,1))>85,CODE(MID(A1,2,1))<=90),CODE(MID(A1,2,1))-52,MID(A1,2,1)))))*2+IF(PROPER(MID(A1,3,1))="A",10,IF(AND(CODE(MID(A1,3,1))>65,CODE(MID(A1,3,1))<=75),CODE(MID(A1,3,1))-54,IF(AND(CODE(MID(A1,3,1))>75,CODE(MID(A1,3,1))<=85),CODE(MID(A1,3,1))-53,IF(AND(CODE(MID(A1,3,1))>85,CODE(MID(A1,3,1))<=90),CODE(MID(A1,3,1))-52,MID(A1,3,1)))))*4+IF(PROPER(MID(A1,4,1))="A",10,IF(AND(CODE(MID(A1,4,1))>65,CODE(MID(A1,4,1))<=75),CODE(MID(A1,4,1))-54,IF(AND(CODE(MID(A1,4,1))>75,CODE(MID(A1,4,1))<=85),CODE(MID(A1,4,1))-53,IF(AND(CODE(MID(A1,4,1))>85,CODE(MID(A1,4,1))<=90),CODE(MID(A1,4,1))-52,MID(A1,4,1)))))*8+MID(A1,5,1)*16+MID(A1,6,1)*32+MID(A1,7,1)*64+MID(A1,8,1)*128+MID(A1,9,1)*256+MID(A1,10,1)*512,11),"VALID","INVALID"),"INVALID")

Below is an Excel array formula for the same function (container number in cell A1):

=IF(LEN(A1)=11,IF(MOD(MOD(SUMPRODUCT(CODE(PROPER(MID(A1,{1,2,3,4},1)))+INT(CODE(PROPER(MID(A1,{1,2,3,4},1)))/11)-60,{1,2,4,8})+SUMPRODUCT(MID(A1,{5,6,7,8,9,10},1)+0,{16,32,64,128,256,512}),11),10)=RIGHT(A1)+0,"VALID","INVALID"),"INVALID")
Code Sample (PHP)

Below is the PHP code to validate a container number:

function checkDigit($mark){    $char2num = ['A'=>10, 'B'=>12, 'C'=>13, 'D'=>14, 'E'=>15, 'F'=>16, 'G'=>17, 'H'=>18, 'I'=>19, 'J'=>20, 'K'=>21, 'L'=>23, 'M'=>24, 'N'=>25, 'O'=>26, 'P'=>27, 'Q'=>28, 'R'=>29, 'S'=>30, 'T'=>31, 'U'=>32, 'V'=>34, 'W'=>35, 'X'=>36, 'Y'=>37, 'Z'=>38];     $acc=0;    $num=str_split($mark);    for($i=0;$i<10;$i++){        if($i<4) $acc+=($char2num[$num[$i]]*pow(2,$i));        else $acc+=$num[$i]*pow(2,$i);    }    $rem = $acc % 11;    if ($rem == 10) $rem = 0;    if(strlen($mark)==11 && $num[10]==$rem) return true;    return false;}

Code Sample (Java) Below is the Java code do validate a container number:

public static boolean isContainerNumberValid(String pCid){    if(pCid == null || pCid.length() != 11){        return false;    }    String char2num = "0123456789A?BCDEFGHIJK?LMNOPQRSTU?VWXYZ";    int sum = 0;    for (int i = 0; i < 10; i++) {        int n = (char2num.indexOf(pCid.charAt(i)));        n *= Math.pow(2, i);        sum += n;    }    int rem = (sum % 11) % 10;    return char2num.indexOf(pCid.charAt(10)) == rem;}
Code Sample (Visual FoxPro)

Below is a VFP codesample, adopted from the above VB sample

Invalid language.

You need to specify a language like this: <source lang="html4strict">...</source>

Supported languages for syntax highlighting:

4cs, 6502acme, 6502kickass, 6502tasm, 68000devpac, abap, actionscript, actionscript3, ada, aimms, algol68, apache, applescript, arm, asm, asp, asymptote, autoconf, autohotkey, autoit, avisynth, awk, bascomavr, bash, basic4gl, bf, bibtex, blitzbasic, bnf, boo, c, caddcl, cadlisp, cfdg, cfm, chaiscript, chapel, cil, clojure, cmake, cobol, coffeescript, cpp, csharp, css, cuesheet, d, dart, dcl, dcpu16, dcs, delphi, diff, div, dos, dot, e, ecmascript, eiffel, email, epc, erlang, euphoria, ezt, f1, falcon, fo, fortran, freebasic, freeswitch, fsharp, gambas, gdb, genero, genie, gettext, glsl, gml, gnuplot, go, groovy, gwbasic, haskell, haxe, hicest, hq9plus, html4strict, html5, icon, idl, ini, inno, intercal, io, ispfpanel, j, java, java5, javascript, jcl, jquery, kixtart, klonec, klonecpp, latex, lb, ldif, lisp, llvm, locobasic, logtalk, lolcode, lotusformulas, lotusscript, lscript, lsl2, lua, m68k, magiksf, make, mapbasic, matlab, mirc, mmix, modula2, modula3, mpasm, mxml, mysql, nagios, netrexx, newlisp, nginx, nimrod, nsis, oberon2, objc, objeck, ocaml, octave, oobas, oorexx, oracle11, oracle8, oxygene, oz, parasail, parigp, pascal, pcre, per, perl, perl6, pf, php, pic16, pike, pixelbender, pli, plsql, postgresql, postscript, povray, powerbuilder, powershell, proftpd, progress, prolog, properties, providex, purebasic, pycon, pys60, python, q, qbasic, qml, racket, rails, rbs, rebol, reg, rexx, robots, rpmspec, rsplus, ruby, rust, sas, scala, scheme, scilab, scl, sdlbasic, smalltalk, smarty, spark, sparql, sql, standardml, stonescript, systemverilog, tcl, teraterm, text, thinbasic, tsql, typoscript, unicon, upc, urbi, uscript, vala, vb, vbnet, vbscript, vedit, verilog, vhdl, vim, visualfoxpro, visualprolog, whitespace, whois, winbatch, xbasic, xml, xpp, yaml, z80, zxbasic


FUNCTION ISO6346Check(cTest AS STRING)        LOCAL i, nResult        nResult = 0                FOR i = 1 TO 10                nResult = nResult + IIF(i < 5, FLOOR(11 * (ASC( SUBSTR(cTest,i,1)) - 56) / 10) + 1, ASC( SUBSTR(cTest,i,1)) - 48) * 2 ^ (i - 1)        ENDFOR                RETURN (nResult - FLOOR(nResult / 11) * 11) % 10ENDFUNC
Code Sample (Eiffel)

Below is an Eiffel code sample.

	check_digit: CHARACTER		note 		local			l_d1, l_d2, l_d3, l_d4, l_d5, l_d6, l_d7, l_d8, l_d9, l_d10,			l_sum1,			l_sum2: INTEGER			l_div_by_11: REAL_64		do			l_d1 := conversion_hash.at (owner_code [1]) * 1			l_d2 := conversion_hash.at (owner_code [2]) * 2			l_d3 := conversion_hash.at (owner_code [3]) * 4			l_d4 := conversion_hash.at (equipment_category_id) * 8			l_d5 := serial_number [1].out.to_integer * 16			l_d6 := serial_number [2].out.to_integer * 32			l_d7 := serial_number [3].out.to_integer * 64			l_d8 := serial_number [4].out.to_integer * 128			l_d9 := serial_number [5].out.to_integer * 256			l_d10 := serial_number [6].out.to_integer * 512			l_sum1 := l_d1 + l_d2 + l_d3 + l_d4 + l_d5 + l_d6 + l_d7 + l_d8 + l_d9 + l_d10			l_div_by_11 := l_sum1 / 11			l_sum2 := l_div_by_11.truncated_to_integer			Result := (l_sum1 - (l_sum2 * 11)).out [1]		end
	conversion_hash: HASH_TABLE [INTEGER, CHARACTER]		once			create Result.make (26)			Result.force (10, 'A')			Result.force (12, 'B')			Result.force (13, 'C')			Result.force (14, 'D')			Result.force (15, 'E')			Result.force (16, 'F')			Result.force (17, 'G')			Result.force (18, 'H')			Result.force (19, 'I')			Result.force (30, 'J')			Result.force (21, 'K')			Result.force (23, 'L')			Result.force (24, 'M')			Result.force (25, 'N')			Result.force (26, 'O')			Result.force (27, 'P')			Result.force (28, 'Q')			Result.force (29, 'R')			Result.force (30, 'S')			Result.force (31, 'T')			Result.force (32, 'U')			Result.force (34, 'V')			Result.force (35, 'W')			Result.force (36, 'X')			Result.force (37, 'Y')			Result.force (38, 'Z')		ensure			has_26: Result.count = 26		end
Code Sample (T-SQL)

Below is a Select statement implementing the above algorithm in T-SQL for Microsoft SQL Server, validating column ContainerNumber on all rows of the dbo.Containers table:

WITH cteNumbers AS (   SELECT ROW_NUMBER() OVER (ORDER BY (SELECT NULL)) AS n   FROM (         SELECT 1 UNION ALL SELECT 1 UNION ALL SELECT 1 UNION ALL SELECT 1 UNION ALL SELECT 1 UNION ALL          SELECT 1 UNION ALL SELECT 1 UNION ALL SELECT 1 UNION ALL SELECT 1 UNION ALL SELECT 1 UNION ALL         SELECT 1      ) t (n))SELECT   cnt.ContainerNumber,   (x.[SUM] % 11) % 10 AS [computed checksum],   SUBSTRING(cnt.ContainerNumber, len(cnt.ContainerNumber), 1) AS [LAST digit],   CASE      WHEN cnt.ContainerNumber NOT LIKE '[A-Za-z][A-Za-z][A-Za-z][A-Za-z][0-9][0-9][0-9][0-9][0-9][0-9][0-9]' THEN 'Incorrect format'      WHEN NULLIF(SUBSTRING(cnt.ContainerNumber, len(cnt.ContainerNumber), 1), CHAR(ascii('0') + (x.[SUM] % 11) % 10)) IS NOT NULL THEN 'Incorrect checksum digit'      ELSE 'Ok'   END AS [STATUS]FROM dbo.Containers cnt   CROSS apply (         SELECT SUM(            POWER(2, n.n - 1) *            CASE                WHEN t.ch BETWEEN '0' AND '9' THEN ascii(t.ch) - ascii('0')               WHEN t.ch = 'A' THEN 10               WHEN t.ch BETWEEN 'B' AND 'K' THEN 12 + ascii(t.ch) - ascii('B')               WHEN t.ch BETWEEN 'L' AND 'U' THEN 23 + ascii(t.ch) - ascii('L')               WHEN t.ch BETWEEN 'V' AND 'Z' THEN 34 + ascii(t.ch) - ascii('V')            END)         FROM cteNumbers n            CROSS apply (                  SELECT UPPER(SUBSTRING(cnt.ContainerNumber, n.n, 1))               ) t (ch)         WHERE n.n < len(cnt.ContainerNumber) -- excluding last digit.      ) x ([SUM])
Code Sample (Go)

Below is a code Snippet implementing the above algorithm in Go validating string "cn":

func ISO6346Check(cn string) bool {        if len(cn) != 11 {                return false        }        cn = strings.ToUpper(cn)        n := 0.0        d := 0.5        for i := 0; i < 10; i++ {                d *= 2                n += d * float64(strings.Index("0123456789A?BCDEFGHIJK?LMNOPQRSTU?VWXYZ", string(cn[i])))        }        return (int(n)-int(n/11)*11)%10 == int(cn[10]-'0')}
Code Sample (R Language)

Below is a code Snippet implementing the Check Digit algorithm in R to validate the string "cntr_no":

validCheckDigit <- function(cntr_no) {    encodeList <- unlist(strsplit('0123456789A?BCDEFGHIJK?LMNOPQRSTU?VWXYZ', split = ''))    cntr_no_split = as.list(unlist(strsplit(toupper(cntr_no), split = '')))     # Details on algorithm can be found here https://en.wikipedia.org/wiki/ISO_6346#Check_Digit     # Step 1    char2num <- sapply(cntr_no_split, function(x, encodeList) {which(x == encodeList)-1}, encodeList = encodeList)    # Step 2    sum_encode <- sum(char2num[1:10] * 2^c(0:9))    # Step 3    sum_encode_check_digit <- (sum_encode %% 11) %% 10     return (sum_encode_check_digit == char2num[11])} # Testcntr_no <- 'CSQU3054383'result <- validCheckDigit(cntr_no)

Practical Problems

In day-to-day business it happens that containers do appear which do not follow the ISO 6346 identification at all; however, they are fully CSC safety approved containers. Usually these are "shippers owned" containers, which means that they are not owned by the carrier but supplied by the cargo owners (shippers). They may have no registered owner code and no category identifier and have no check digit. It is advisable to follow ISO 6346 as the absence of a compliant identification code causes problems for both carriers and container terminals to correctly identify the equipment and properly deliver the cargo, because computer systems require ISO 6346 conformant naming and as such missing prefixes are invented. For example, YYYY at the carrier and XXXX at the terminal causes the equipment to mismatch. Moreover, since ISO 6346 identification has become a requirement in international Customs conventions (Customs Conventions on Containers and Istanbul Convention), many Customs Administrations have begun validating that containers are marked as per the standard.

Size and Type Codes

The codes are compiled of the following elements:

  • First character, representing the length (coded)
  • Second character, representing the width and height (coded)
  • Third and fourth character indicating the type of the container

The following is an overview of the most common codes:

ISO Type GroupISO Size Type
CodeDescriptionCodeDescription
20GPGENERAL PURPOSE CONT.20G0GENERAL PURPOSE CONT.
20G1GENERAL PURPOSE CONT.
20HRISOLADO CONTAINE REEFER20H0INSULATED CONTAINER
20PFFLAT (FIXED ENDS)20P1FLAT (FIXED ENDS)
20TDTANK CONTAINER20T3TANK CONTAINER
20T4TANK CONTAINER
20T5TANK CONTAINER
20T6TANK CONTAINER
20TGTANK CONTAINER20T7TANK CONTAINER
20T8TANK CONTAINER
20TNTANK CONTAINER20T0TANK CONTAINER
20T1TANK CONTAINER
20T2TANK CONTAINER
22BUBULK CONTAINER22B0BULK CONTAINER
22GPGENERAL PURPOSE CONT.22G0GENERAL PURPOSE CONT.
22G1GENERAL PURPOSE CONT.
22HRINSULATED CONTAINER22H0INSULATED CONTAINER
22PCFLAT (COLLAPSIBLE)22P3FLAT (COLLAPSIBLE)
22P8FLAT (COLL.FLUSH FOLDING)
22P9FLAT (COLLAPSIBLE)
22PFFLAT (FIXED ENDS)22P1FLAT (FIXED ENDS)
22P7FLAT (GENSET CARRIER)
22RCREEFER CONT.(NO FOOD)22R9REEFER CONT.(NO FOOD)
22RSBUILT-IN GEN. F. POWER SPLY OF REEF22R7BUILT-IN GEN. F. POWER SPLY OF REEF
22RTREEFER CONTAINER22R1REEFER CONTAINER
22SNNAMED CARGO CONTAINER22S1NAMED CARGO CONTAINER
22TDTANK CONTAINER22T3TANK CONTAINER
22T4TANK CONTAINER
22T5TANK CONTAINER
22T6TANK CONTAINER
22TGTANK CONTAINER22T7TANK CONTAINER
22T8TANK CONTAINER
22TNTANK CONTAINER22T0TANK CONTAINER
22T1TANK CONTAINER
22T2TANK CONTAINER
22UPHARDTOP CONTAINER22U6HARDTOP CONTAINER
22UTOPEN TOP CONTAINER22U1OPEN TOP CONTAINER
22VHVENTILATED CONTAINER22V0VENTILATED CONTAINER
22V2VENTILATED CONTAINER
22V3VENTILATED CONTAINER
25GPGP-CONTAINER OVER-HEIGHT25G0GP-CONTAINER OVER-HEIGHT
26GPGP-CONTAINER OVER-HEIGHT26G0GP-CONTAINER OVER-HEIGHT
26HRINSULATED CONTAINER26H0INSULATED CONTAINER
28TGTANK FOR GAS28T8TANK FOR GAS
28UTOPEN TOP (HALF HEIGHT)28U1OPEN TOP (HALF HEIGHT)
28VHVE-HALF-HEIGHT =1448 MM HEIGHT28V0VE-HALF-HEIGHT =1448 MM HEIGHT
29PLPLATFORM29P0PLATFORM
2EGPGEN. PURP. WITHOUT VENT WIDTH 2.5M2EG0HIGH CUBE CONT. (WIDTH 2.5M)
42GPGENERAL PURPOSE CONT.42G0GENERAL PURPOSE CONT.
42G1GENERAL PURPOSE CONT.
42HRINSULATED CONTAINER42H0INSULATED CONTAINER
42PCFLAT (COLLAPSIBLE)42P3FLAT (COLLAPSIBLE)
42P8FLAT (COLL.FLUSH FOLDING)
42P9FLAT (COLLAPSIBLE)
42PFFLAT (FIXED ENDS)42P1FLAT (FIXED ENDS)
42PSFLAT (SPACE SAVER)42P6FLAT SPACE SAVER
42RCREEFER CONT.(NO FOOD)42R9REEFER CONT.(NO FOOD)
42RSREEFER CONT.(DIESEL GEN.)42R3REEFER CONT.(DIESEL GEN.)
42RTREEFER CONTAINER42R1REEFER CONTAINER
42SNNAMED CARGO CONTAINER42S1NAMED CARGO CONTAINER
42TDTANK CONTAINER42T5TANK CONTAINER
42T6TANK CONTAINER
42TGTANK CONTAINER42T8TANK CONTAINER
42TNTANK CONTAINER42T2TANK CONTAINER
42UPHARDTOP CONTAINER42U6HARDTOP CONTAINER
42UTOPEN TOP CONTAINER42U1OPEN TOP CONTAINER
45BKBULK CONTAINER45B3BULK CONTAINER
45GPHIGH CUBE CONT.45G0HIGH CUBE CONT.
45G1HIGH CUBE CONT.
45PCFLAT (COLLAPSIBLE)45P3FLAT (COLLAPSIBLE)
45P8FLAT (COLL.FLUSH FOLDING)
45RCREEFER CONT.(NO FOOD)45R9REEFER CONT.(NO FOOD)
45RTREEFER HIGHCUBE CONTAINER45R1REEFER HIGHCUBE CONTAINER
45UTOPEN TOP CONTAINER45U1OPEN TOP CONTAINER
45UPHIGH CUBE HARDTOP CONT.45U6HIGH CUBE HARDTOP CONT.
46HRINSULATED CONTAINER46H0INSULATED CONTAINER
48TGTANK FOR GAS48T8TANK FOR GAS
49PLPLATFORM49P0PLATFORM
4CGPGP CONTAINER4CG0GP CONTAINER (WIDTH 2.5 M)
L0GPHIGH CUBE CONT.L0G1HIGH CUBE CONT.
L2GPHIGH CUBE CONT.L2G1HIGH CUBE CONT.
L5GPHIGH CUBE CONT.L5G1HIGH CUBE CONT.

Use the below to calculate Size/Type of a less commonly used ISO 6346 containers:

ISO Length CodesSecond size code character
CodeContainer lengthCodeContainer heightWidth
110′08′8′
220′28′6″
330′49′
440′59′6″
B24′6> 9′6″
C24′6″84′3″
G41′9<= 4′
H43′C8′6″2348mm < x <= 2500mm
L45′D9′
M48′E9′6″
N49′F> 9′6″
ISO Type Codes
CodeDescription
G0General - Openings at one or both ends
G1General - Passive vents at upper part of cargo space
G2General - Openings at one or both ends + full openings on one or both sides
G3General - Openings at one or both ends + partial openings on one or both sides
V0Fantainer - Non-mechanical, vents at lower and upper parts of cargo space
V2Fantainer - Mechanical ventilation system located internally
V4Fantainer - Mechanical ventilation system located externally
R0Integral Reefer - Mechanically refrigerated
R1Integral Reefer - Mechanically refrigerated and heated
R2Integral Reefer - Self-powered mechanically refrigerated
R3Integral Reefer - Self-powered mechanically refrigerated and heated
H0Refrigerated or heated with removable equipment located externally; heat transfer coefficient K=0.4W/M2.K
H1Refrigerated or heated with removable equipment located internally
H2Refrigerated or heated with removable equipment located externally; heat transfer coefficient K=0.7W/M2.K
H5Insulated - Heat transfer coefficient K=0.4W/M2.K
H6Insulated - Heat transfer coefficient K=0.7W/M2.K
U0Open Top - Openings at one or both ends
U1Open Top - Idem + removable top members in end frames
U2Open Top - Openings at one or both ends + openings at one or both sides
U3Open Top - Idem + removable top members in end frames
U4Open Top - Openings at one or both ends + partial on one and full at other side
U5Open Top - Complete, fixed side and end walls ( no doors )
T0Tank - Non dangerous liquids, minimum pressure 0.45 bar
T1Tank - Non dangerous liquids, minimum pressure 1.50 bar
T2Tank - Non dangerous liquids, minimum pressure 2.65 bar
T3Tank - Dangerous liquids, minimum pressure 1.50 bar
T4Tank - Dangerous liquids, minimum pressure 2.65 bar
T5Tank - Dangerous liquids, minimum pressure 4.00 bar
T6Tank - Dangerous liquids, minimum pressure 6.00 bar
T7Tank - Gases, minimum pressure 9.10 bar
T8Tank - Gases, minimum pressure 22.00 bar
T9Tank - Gases, minimum pressure to be decided
B0Bulk - Closed
B1Bulk - Airtight
B3Bulk - Horizontal discharge, test pressure 1.50 bar
B4Bulk - Horizontal discharge, test pressure 2.65 bar
B5Bulk - Tipping discharge, test pressure 1.50 bar
B6Bulk - Tipping discharge, test pressure 2.65 bar
P0Flat or Bolster - Plain platform
P1Flat or Bolster - Two complete and fixed ends
P2Flat or Bolster - Fixed posts, either free-standing or with removable top member
P3Flat or Bolster - Folding complete end structure
P4Flat or Bolster - Folding posts, either free-standing or with removable top member
P5Flat or Bolster - Open top, open ends (skeletal)
S0Livestock carrier
S1Automobile carrier
S2Live fish carrier

Country Code (Optional)

The country code consists of two capital letters of the Latin alphabet as described in ISO 3166. It indicates the country where the code is registered not the nationality of the owner or operator of the container. The letters of the code shall not be less than 100 mm high.

Mandatory Operational Marks

Operational marks are intended solely to convey information requested for the movement of containers or give visual warnings. They relate to

  • the weight of containers
  • a symbol to denote air-surface container
  • a sign warning of overhead electrical danger
  • height marks for containers higher than 2.6 m (8 ft 6 in)

See also

The following is a list of further freight container related ISO specifications, where not all have an article assigned yet (you can help improve Wikipedia and start one):

  • ISO 668 - Freight containers - Classification, dimensions and ratings
  • ISO 830 - Freight containers - Terminology
  • ISO 1161 - Freight containers - Corner fittings - Specification
  • ISO 1496 - Freight containers - Specification and testing
  • ISO 2308 - Hooks for lifting freight containers of up to 30 tons capacity - Basic requirements
  • ISO 3874 - Freight containers - Handling and securing
  • ISO 8323 - Freight containers - Air/surface (intermodal) general purpose containers - Specification and tests
  • ISO 9669 - Freight containers - Interface connections for tank containers
  • ISO 9711 - Freight containers - Information related to containers on board vessels
  • ISO 9897 - Container equipment data exchange (CEDEX)
  • ISO 10368 - Freight thermal containers - Remote condition monitoring
  • ISO 10374 - Freight containers - Automatic identification

References

External links

Text is available under the Creative Commons Attribution-ShareAlike License; additional terms may apply. By using this site, you agree to the Terms of Use and Privacy Policy. Wikipedia is a registered trademark of the Wikimedia Foundation, Inc., a non-profit organization.

Also On Wow

    Advertisement

    Trending Now