A.Eiderman, I.Marelus Internet Draft Netstrap Ltd. POB 45020 Har Hotzvim, Jerusalem, ISRAEL 91450 Document: draft-netstrap-binary-encod-conver-00.txt March, 2001 Category: Fast Binary/ASCII Encoding conversion METHOD OF ENCODING BINARY DATA (Version I) draft-netstrap-binary-encod-conver-00.txt Status of this Memo This document is an Internet-Draft and is in full conformance with all provisions of Section 10 of RFC2026 except that the right to produce derivative works is not granted. Internet-Drafts are working documents of the Internet Engineering Task Force (IETF), its areas and its working groups. Note that other groups may also distribute working documents as Internet-Drafts. Internet-Drafts are draft documents valid for a maximum of six months and may be updated, replaced, or obsoleted by other documents at any time. It is inappropriate to use Internet-Drafts as reference material or to cite them other than as "work in progress". The list of current Internet-Drafts can be accessed at http://www.ietf.org/ietf/lid-abstracts.txt The list of Internet-Draft Shadow Directories can be accessed at http://www.ietf.org/shadow.html 1. Abstract A patent-pending method of encoding binary data for transfer between computers connected via a network, in which the encoded data optimally has an expansion ratio of about 1.22 (22%). Generally, the method relates to transfering binary data over the network using 94 ASCII printable characters by fast encoding. Specifically, the method includes breaking the data into a plurality of chunks, and substantially performing some MOD and INT operations on these chunks according to predefined combinatorial conditions. NOTE: This RFC includes Background, Summary, and Detailed Description Sections - for those wanting to understand the method; and a Working Prototype (section 2.0) - for those wanting to quickly implement and measure the qualities of improvement described; specifically as "C-LANGUAGE IMPLEMENTATION DEMO" (section 5.0). 2. Conventions used in this document The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as described in RFC-2119 [ ]. 3. BACKGROUND While computer networks, such as local area networks, have existed for many years, the problem of encoding binary data for transmission between client computers has become a widespread global consideration since the advent of the Internet and e-mail.By way of introduction, it is known that a single byte contains up to 8 bits of information, each of which has a value between 0 and 255, as per the IBM EBCDIC (Extended Binary Coded Decimal Interchange Code). It is further known that, in the ASCII system, each of the 128 characters has a numerical code from 0-127, such that, for example, the letter "B" has a value of 66, the letter "D" has a value of 68, and so on. Additional characters may be assigned, in an 8 bit system, predetermined numerical values from 128 to 255. However, as some data receiving protocols are based on a 7 bit data system, 8 bit data must be divided into two bytes. A problem stemming from transmission of data between computers is caused by the fact that all computer files which contain other than the standard 95 ASCII characters, whether these files contain text, image or sound data, must be not only encoded so as to render them transmittable, but also decodable by software resident on recipient computers which may have different operating systems employing different compilers. Examples of some of the different systems used are DOS and Windows 95/98, which are used by PC's, as well as those employed by Unix and Macintosh computers. Solutions which exist for preparing binary data for transmission over the Internet all entail the use of encoding routines which, due to the transformation of the data into a decodable binary format, expand the data. The expanded data also requires a certain transmission time corresponding, inter alia, to the volume of transmitted data. Clearly, a certain time is also taken to encode the data at the computer of origin, and to decode the data at the recipient computer, prior to rendering the data accessible thereat. Currently, two encoding systems are used for facilitating binary data transmission, 3 to 4 byte systems (herein referred to as "3to4"), such as the so-called UUencode, "XX", "MIME64", and "BinHex", wherein 3 bytes are encoded into a 4 byte form, so as to have an expansion ratio of approximately 1.33 (33%) in the volume of data; and the "BtoA" system, wherein 4 bytes are encoded into a 5 byte form, so as to have an expansion ratio of only 1.25 (25%). In conventional communications systems, both calculation time and transmission time are factors governing the overall encode-to-decode time (where data is encoded at a first station and decoding is performed at a second station, remote from the first station). Due to the relative slowness of many public networks, however, via which many consumers access the Internet, and send electronic mail, the expansion ratio is of great significance. Clearly, the smaller the expansion ratio, the less time it will take to transmit encoded data. In known systems, the smallest expansion ratio is 1.25 (25%), for the BtoA system, described above. 4. SUMMARY The present method seeks to provide an improvement in encoding binary data for transmission between two or more computers, in which the encoded data has an expansion ratio of less than 1.25 (25%), preferably 1.22 (22%), thereby reducing the time required for transmission of the encoded data. There is thus provided a method of encoding binary data for transfer from a computer of origin to a recipient computer, which includes the following steps: (i) dividing a portion of unencoded data, having a predetermined number of bytes Bn into a plurality n of chunks; (ii) mathematically processing the value of each of n-1 chunks as a function of at least a predetermined number, so as to produce a modulo MOD and an integer INT; (iii) entering a predetermined one of the MOD and INT of each of the n-1 chunks into N-x predetermined bytes of an encoded sequence having a total of N bytes, wherein x is greater than or equal to 1; and (iv) mathematically processing the other of the MOD and INT of each of the n-1 chunks so as to produce therefor results for entry into the remaining at least one byte of the encoded sequence, wherein the ratio N to Bn is less than 1.25.Additionally, the step (ii) of mathematically processing includes the step of dividing the value of at least one of the n-1 chunks by a predetermined number so as to produce a MOD whose value is equal to or greater than the predetermined number, and the method further includes the additional steps of (v) further dividing the other of the MOD and INT by the predetermined number, thereby to produce further MOD and INT, and (vi) entering the predetermined one of the further MOD and further INT into a predetermined byte of the encoded sequence; and, if the further MOD has a value which is equal to or greater than the predetermined number, repeating the step (v) of further dividing, and the step (vi) of entering, until the value of the further MOD is less than the predetermined number. Furthermore, the one or more n-1 chunks is all of the n-1 chunks. Additionally, the step (iv) of mathematically processing includes the step of mathematically processing the other of the MOD and INT as a function of at least a predetermined multiplier and the predetermined number, so as to produce a modulo MOD and an integer INT. Furthermore, step (iv) includes mathematically processing the other of the MOD and INT as a function also of a predetermined subsequent chunk in the unencoded sequence.Additionally, the predetermined number equals the encoding base of the present method, which, preferably is 94, such that the ratio N to Bn = 11/9. Furthermore, the predetermined number is a different, predetermined number for each of the n-1 chunks. 5. DETAILED DESCRIPTION There is herein provided an improved method of encoding binary data for transmission between two or more computers, such that the encoded data has an expansion ratio of less than 1.25. More particularly, there is provided a method of encoding binary data employing a 9 to 11 system, in which unencoded data has a sequence of Bn bytes, and the encoded data corresponding thereto has a sequence of N bytes, thereby to provide an expansion ratio N to Bn of 11/9 or 1.22. It will be appreciated that the description of 9to11 encoding is also intended to include multiples of 9to11, including, by way of example, 18 to 22, and 36 to 44 in which, while the amount of data being encoded at any one time is proportionately greater than in the present 9to11 system, the expansion ratio remains 1.22 (22%). It will be particularly noted that the 9to11 expansion, is particularly advantageous with respect to either the 3 to4 or 4 to5 methods, which, for a 9 byte unencoded word would result in 12 and 11.25 byte encoded words, respectively. As will be appreciated from the following description, the encoding may be implemented by use of various novel routines. However, each such routine implements the 9 to 11 method, resulting in a smaller volume of encoded data for a given unencoded data block, thus also facilitating a shorter transmission time for a given volume of unencoded data at a given rate of transmission. The method employs a table having 94 characters, this thus being the encoding calculation "base", as evident from the following description. 6. TERMS In the context of the working prototype, a "byte" means eight-bit quantity. Each byte can be described as array of 8 bit, from bit number 0 to bit number 7, where the bit number 0 is the highest (More Significant Bit, MSB) and bit number 7 is the lowest (Less Significant Bit, LSB). Each word can be described as array of 16 bit, from bit number 0 to bit number 15, where the bit number 0 is the highest (More Significant Bit, MSB) and bit number 15 is the lowest (Less Significant Bit, LSB). Let "x=y" denote "set x equal to y". Let "x*y" denote "multiplication of x by y" Let "x/y" denote "integer part of division of x by y". Let "x%y" denote "modulo of division of x by y". Let "x< #define FALSE 0 #define TRUE 1 #define VERSION "0.8" void main(argc, argv) int argc; unsigned char **argv; { unsigned char error, bBinaryToASCII; FILE *fInputFile, *fOutputFile; int iReadBytes, iConvertedBytes, iWrittenBytes; unsigned char cReadBuffer[11], cWriteBuffer[11]; error = FALSE; if(argc >= 4 && argv[1][0] == '-') { switch(argv[1][1]) { case 'a' : bBinaryToASCII = FALSE; break; case 'b' : bBinaryToASCII = TRUE; break; case 'A' : bBinaryToASCII = FALSE; break; case 'B' : bBinaryToASCII = TRUE; break; default : error = TRUE; } } else error = TRUE; if (error) { fprintf(stderr, "\nntec - nine to eleven coding (version %s)\n", VERSION); fprintf(stderr, "(c) aryeh eiderman netstrap ltd.\n"); fprintf(stderr, "\nusage: ntec command inputfile outputfile\n"); fprintf(stderr, "\nwhere: command is -a for decoding (ascii to binary)"); fprintf(stderr, "\n -b for encoding (binary to ascii)"); fprintf(stderr, "\n"); } else { if ((fInputFile = fopen(argv[2], "rb")) != NULL ) { if ((fOutputFile = fopen(argv[3], "wb")) != NULL ) { if (bBinaryToASCII) { iReadBytes = 9; iConvertedBytes = 11; iWrittenBytes = 11; while ((iReadBytes == 9) && (iConvertedBytes == iWrittenBytes)) { if ((iReadBytes = fread(cReadBuffer, 1, 9, fInputFile)) > 0); { iConvertedBytes = NTEEncode(cReadBuffer, iReadBytes, cWriteBuffer); iWrittenBytes = fwrite(cWriteBuffer, 1, iConvertedBytes, fOutputFile); } } } else { iReadBytes = 11; iConvertedBytes = 9; iWrittenBytes = 9; while ((iReadBytes == 11) && (iConvertedBytes == iWrittenBytes)) { if ((iReadBytes = fread(cReadBuffer, 1, 11, fInputFile)) > 0) { iConvertedBytes = NTEDecode(cReadBuffer, iReadBytes, cWriteBuffer); iWrittenBytes = fwrite(cWriteBuffer, 1, iConvertedBytes, fOutputFile); } } } { } if (iConvertedBytes != iWrittenBytes) { fprintf(stderr, "\nerror on writing to %s\n", argv[3]); error = TRUE; } fclose(fOutputFile); } else { fprintf(stderr, "\ncan't write to %s\n", argv[3]); error = TRUE; } fclose(fInputFile); } else { fprintf(stderr, "\ncan't open %s\n", argv[2]); error = TRUE; } } if (error) exit(1); } int NTEEncode(cInBuffer, iInBufferSize, cOutBuffer) unsigned char *cInBuffer; int iInBufferSize; unsigned char *cOutBuffer; { unsigned int wBlock; unsigned char cBlock; int iCounter, iResNum; iResNum = 0; if (iInBufferSize == 9) { iCounter = 0; wBlock = cInBuffer[iCounter++]; /* 1st in */ cBlock = cInBuffer[iCounter++]; /* 2nd in */ wBlock = (wBlock << 5) | (cBlock >> 3); cOutBuffer[iResNum++] = DMFE(&wBlock); /* 1st out */ wBlock = (wBlock << 3) | (cBlock & 0x07); cBlock = cInBuffer[iCounter++]; /* 3rd in */ wBlock = (wBlock << 3) | (cBlock >> 5); cOutBuffer[iResNum++] = DMFE(&wBlock); /* 2nd out */ wBlock = (wBlock << 5) | (cBlock & 0x1f); cBlock = cInBuffer[iCounter++]; /* 4th in */ wBlock = (wBlock << 2) | (cBlock >> 6); cOutBuffer[iResNum++] = DMFE(&wBlock); /* 3rd out */ wBlock = (wBlock << 6) | (cBlock & 0x3f); cOutBuffer[iResNum++] = DMFE(&wBlock); /* 4th out */ cBlock = cInBuffer[iCounter++]; /* 5th in */ wBlock = (wBlock << 7) | (cBlock >> 1); cOutBuffer[iResNum++] = DMFE(&wBlock); /* 5th out */ wBlock = (wBlock << 1) | (cBlock & 0x01); cBlock = cInBuffer[iCounter++]; /* 6th in */ wBlock = (wBlock << 5) | (cBlock >> 3); cOutBuffer[iResNum++] = DMFE(&wBlock); /* 6th out */ wBlock = (wBlock << 3) | (cBlock & 0x07); cBlock = cInBuffer[iCounter++]; /* 7th in */ wBlock = (wBlock << 4) | (cBlock >> 4); cOutBuffer[iResNum++] = DMFE(&wBlock); /* 7th out */ wBlock = (wBlock << 4) | (cBlock & 0x0f); cBlock = cInBuffer[iCounter++]; /* 8th in */ wBlock = (wBlock << 2) | (cBlock >> 6); cOutBuffer[iResNum++] = DMFE(&wBlock); /* 8th out */ wBlock = (wBlock << 6) | (cBlock & 0x3f); cBlock = cInBuffer[iCounter++]; /* 9th in */ wBlock = (wBlock << 1) | (cBlock >> 7); cOutBuffer[iResNum++] = DMFE(&wBlock); /* 9th out */ wBlock = (wBlock << 6) | ((cBlock >> 1) & 0x3f); cOutBuffer[iResNum++] = DMFE(&wBlock); /* 10th out */ wBlock = (wBlock << 1) | (cBlock & 0x01); cOutBuffer[iResNum++] = wBlock + 33; /* 11th out */ } else if (iInBufferSize > 0) { iCounter = 0; wBlock = cInBuffer[iCounter++]; /* 1st in */ wBlock = wBlock << 5; if (iInBufferSize > 1) { cBlock = cInBuffer[iCounter++]; /* 2nd in */ wBlock = wBlock | (cBlock >> 3); cOutBuffer[iResNum++] = DMFE(&wBlock); /* 1st out */ wBlock = ((wBlock << 3) | (cBlock & 0x07)) << 3; if (iInBufferSize > 2) { cBlock = cInBuffer[iCounter++]; /* 3rd in */ wBlock = wBlock | (cBlock >> 5); cOutBuffer[iResNum++] = DMFE(&wBlock); /* 2nd out */ wBlock = ((wBlock << 5) | (cBlock & 0x1f)) << 2; if (iInBufferSize > 3) { cBlock = cInBuffer[iCounter++]; /* 4th in */ wBlock = wBlock | (cBlock >> 6); cOutBuffer[iResNum++] = DMFE(&wBlock); /* 3rd out */ wBlock = (wBlock << 6) | (cBlock & 0x3f); cOutBuffer[iResNum++] = DMFE(&wBlock); /* 4th out */ if (iInBufferSize > 4) { cBlock = cInBuffer[iCounter++]; /* 5th in */ wBlock = (wBlock << 7) | (cBlock >> 1); cOutBuffer[iResNum++] = DMFE(&wBlock); /* 5th out */ wBlock = ((wBlock << 1) | (cBlock & 0x01)) << 5; if (iInBufferSize > 5) { cBlock = cInBuffer[iCounter++]; /* 6th in */ wBlock = wBlock | (cBlock >> 3); cOutBuffer[iResNum++] = DMFE(&wBlock); /* 6th out */ wBlock = ((wBlock << 3) | (cBlock & 0x07)) << 4; if (iInBufferSize > 6) { cBlock = cInBuffer[iCounter++]; /* 7th in */ wBlock = wBlock | (cBlock >> 4); cOutBuffer[iResNum++] = DMFE(&wBlock); /* 7th out */ wBlock = ((wBlock << 4) | (cBlock & 0x0f)) << 2; if (iInBufferSize == 8) { cBlock = cInBuffer[iCounter++]; /* 8th in */ wBlock = wBlock | (cBlock >> 6); cOutBuffer[iResNum++] = DMFE(&wBlock); /* 8th out */ wBlock = ((wBlock << 6) | (cBlock & 0x3f)) << 1; cOutBuffer[iResNum++] = DMFE(&wBlock); /* 9th out */ } else cOutBuffer[iResNum++] = DMFE(&wBlock); /* 7th out */ } else cOutBuffer[iResNum++] = DMFE(&wBlock); /* 6th out */ } else cOutBuffer[iResNum++] = DMFE(&wBlock); /* 5th out */ } } else cOutBuffer[iResNum++] = DMFE(&wBlock); /* 3rd out */ } else cOutBuffer[iResNum++] = DMFE(&wBlock); /* 2nd out */ } else cOutBuffer[iResNum++] = DMFE(&wBlock); /* 1st out */ cOutBuffer[iResNum++] = wBlock + 33; /* last out */ } return iResNum; } /* Assembler way is faster than C, but the FASTEST way is THE TABLE USAGE */ int DMFE(wBlock) /* DivModForEncode */ unsigned int *wBlock; { unsigned char cResult; #if USE_ASM /* FOR INTEL PROCESSOR */ unsigned int wB; wB = *wBlock; asm { mov cx,94 mov ax,wB div cl add ah,33 mov cResult,ah xor ah,ah mov wB,ax } *wBlock = wB; #else cResult = (*wBlock % 94) + 33; *wBlock = *wBlock / 94; #endif return cResult; } int NTEDecode(cInBuffer, iInBufferSize, cOutBuffer) unsigned char *cInBuffer; int iInBufferSize; unsigned char *cOutBuffer; { unsigned int wBlock; unsigned char cBlock; int iPos, iResNum; if (iInBufferSize == 11) { iResNum = 9; iPos = 11; wBlock = cInBuffer[--iPos] - 33; /* 11th in */ cBlock = wBlock & 0x01; wBlock = ((wBlock >> 1) * 94) + (cInBuffer[--iPos] - 33); /* 10th in */ cBlock = ((wBlock & 0x3f) << 1) | cBlock; wBlock = ((wBlock >> 6) * 94) + (cInBuffer[--iPos] - 33); /* 9th in */ cBlock = ((wBlock & 0x01) << 7) | cBlock; cOutBuffer[--iResNum] = cBlock; /* 9th out */ cBlock = (wBlock >> 1) & 0x3f; wBlock = ((wBlock >> 7) * 94) + (cInBuffer[--iPos] - 33); /* 8th in */ cBlock = ((wBlock & 0x03) << 6) | cBlock; cOutBuffer[--iResNum] = cBlock; /* 8th out */ cBlock = (wBlock >> 2) & 0x0f; wBlock = ((wBlock >> 6) * 94) + (cInBuffer[--iPos] - 33); /* 7th in */ cBlock = ((wBlock & 0x0f) << 4) | cBlock; cOutBuffer[--iResNum] = cBlock; /* 7th out */ cBlock = (wBlock >> 4) & 0x07; wBlock = ((wBlock >> 7) * 94) + (cInBuffer[--iPos] - 33); /* 6th in */ cBlock = ((wBlock & 0x1f) << 3) | cBlock; cOutBuffer[--iResNum] = cBlock; /* 6th out */ cBlock = (wBlock >> 5) & 0x01; wBlock = ((wBlock >> 6) * 94) + (cInBuffer[--iPos] - 33); /* 5th in */ cBlock = ((wBlock & 0x7f) << 1) | cBlock; cOutBuffer[--iResNum] = cBlock; /* 5th out */ wBlock = ((wBlock >> 7) * 94) + (cInBuffer[--iPos] - 33); /* 4th in */ cBlock = wBlock & 0x3f; wBlock = ((wBlock >> 6) * 94) + (cInBuffer[--iPos] - 33); /* 3rd in */ cBlock = ((wBlock & 0x03) << 6) | cBlock; cOutBuffer[--iResNum] = cBlock; /* 4th out */ cBlock = (wBlock >> 2) & 0x1f; wBlock = ((wBlock >> 7) * 94) + (cInBuffer[--iPos] - 33); /* 2nd in */ cBlock = ((wBlock & 0x07) << 5) | cBlock; cOutBuffer[--iResNum] = cBlock; /* 3rd out */ cBlock = (wBlock >> 3) & 0x07; wBlock = ((wBlock >> 6) * 94) + (cInBuffer[--iPos] - 33); /* 1st in */ cBlock = ((wBlock & 0x1f) << 3) | cBlock; cOutBuffer[--iResNum] = cBlock; /* 2nd out */ cBlock = wBlock >> 5; cOutBuffer[--iResNum] = cBlock; /* 1st out */ iResNum = 9 - iResNum; } else if (iInBufferSize > 0) { iPos = iInBufferSize; wBlock = cInBuffer[--iPos] - 33; /* last in */ cBlock = 0; if (iInBufferSize == 10) { iResNum = 8; wBlock = ((wBlock >> 6) * 94) + (cInBuffer[--iPos] - 33); /* 9th in */ cBlock = ((wBlock >> 1) & 0x3f); wBlock = wBlock >> 7; } if (iInBufferSize > 8) { wBlock = (wBlock * 94) + (cInBuffer[--iPos] - 33); /* 8th in */ cBlock = ((wBlock & 0x03) << 6) | cBlock; if (iInBufferSize > 9) cOutBuffer[7] = cBlock; /* 8th out */ else iResNum = 7; cBlock = ((wBlock >> 2) & 0x0f); wBlock = wBlock >> 6; } if (iInBufferSize > 7) { wBlock = (wBlock * 94) + (cInBuffer[--iPos] - 33); /* 7th in */ cBlock = ((wBlock & 0x0f) << 4) | cBlock; if (iInBufferSize > 8) cOutBuffer[6] = cBlock; /* 7th out */ else iResNum = 6; cBlock = ((wBlock >> 4) & 0x07); wBlock = wBlock >> 7; } if (iInBufferSize > 6) { wBlock = (wBlock * 94) + (cInBuffer[--iPos] - 33); /* 6th in */ cBlock = ((wBlock & 0x1f) << 3) | cBlock; if (iInBufferSize > 7) cOutBuffer[5] = cBlock; /* 6th out */ else iResNum = 5; cBlock = ((wBlock >> 5) & 0x01); wBlock = wBlock >> 6; } if (iInBufferSize > 5) { wBlock = (wBlock * 94) + (cInBuffer[--iPos] - 33); /* 5th in */ cBlock = ((wBlock & 0x7f) << 1) | cBlock; if (iInBufferSize > 6) cOutBuffer[4] = cBlock; /* 5th out */ else iResNum = 4; wBlock = wBlock >> 7; } if (iInBufferSize > 4) { wBlock = (wBlock * 94) + (cInBuffer[--iPos] - 33); /* 4th in */ cBlock = wBlock & 0x3f; if (iInBufferSize == 5) iResNum = 4; wBlock = wBlock >> 6; } if (iInBufferSize > 3) { wBlock = (wBlock * 94) + (cInBuffer[--iPos] - 33); /* 3rd in */ cBlock = ((wBlock & 0x03) << 6) | cBlock; if (iInBufferSize > 4) cOutBuffer[3] = cBlock; /* 4th out */ else iResNum = 3; cBlock = ((wBlock >> 2) & 0x1f); wBlock = wBlock >> 7; } if (iInBufferSize > 2) { wBlock = (wBlock * 94) + (cInBuffer[--iPos] - 33); /* 2nd in */ cBlock = ((wBlock & 0x07) << 5) | cBlock; if (iInBufferSize > 3) cOutBuffer[2] = cBlock; /* 3th out */ else iResNum = 2; cBlock = ((wBlock >> 3) & 0x07); wBlock = wBlock >> 6; } if (iInBufferSize > 1) { wBlock = (wBlock * 94) + (cInBuffer[--iPos] - 33); /* 1st in */ cBlock = ((wBlock & 0x1f) << 3) | cBlock; if (iInBufferSize > 2) cOutBuffer[1] = cBlock; /* 2nd out */ else iResNum = 1; wBlock = wBlock >> 5; cOutBuffer[0] = wBlock; /* 1st out */ } else iResNum = 0; } return iResNum; } 11. AuthorsĘ Address A.Eiderman, I.Marelus Netstrap Ltd. POB 45020 Har Hotzvim, Jerusalem, 91450 ISRAEL http://www.netstrap.com Full Copyright Statement "Copyright (C) The Internet Society (date). All Rights Reserved. This document and translations of it may be copied and furnished to others, and derivative works that comment on or otherwise explain it or assist in its implementation may be prepared, copied, published and distributed, in whole or in part, without restriction of any kind, provided that the above copyright notice and this paragraph are included on all such copies and derivative works. However, this document itself may not be modified in any way, such as by removing the copyright notice or references to the Internet Society or other Internet organizations, except as needed for the purpose of developing Internet standards in which case the procedures for copyrights defined in the Internet Standards process must be followed, or as required to translate it into languages other than English. <2001> INTERNET BINARY CODING- 2020 15