Fabrice's weblog

Tools and Source

News

My .NET Toolbox
An error occured. See the script errors signaled by your web browser.
No tools selected yet
.NET tools by SharpToolbox.com

Read sample chapters or buy LINQ in Action now!
Our LINQ book is also available on AMAZON

.NET jobs

Emplois .NET

transatlantys hot news

Contact

Me

Others

Selected content

ISBN-13 to ISBN-10

If for some reason you need to convert an ISBN-13 to ISBN-10 (one being that Amazon doesn't support ISBN-13 in product affiliate links) then you need not only to remove the first three characters. You also need to recompute the checksum.

Here is a piece of code that I wrote to handle this conversion:

public static String Isbn13to10(String isbn13)
{
  if (String.IsNullOrEmpty(isbn13))
    throw new ArgumentNullException("isbn13");
  isbn13 = isbn13.Replace("-", "").Replace(" ", "");
  if (isbn13.Length != 13)
    throw new ArgumentException("The ISBN doesn't contain 13 characters.", "isbn13");

  String isbn10 = isbn13.Substring(3, 9);
  int checksum = 0;
  int weight = 10;

  foreach (Char c in isbn10)
  {
    checksum += (int)Char.GetNumericValue(c) * weight;
    weight--;
  }

  checksum = 11-(checksum % 11);
  if (checksum == 10)
    isbn10 += "X";
  else if (checksum == 11)
    isbn10 += "0";
  else
    isbn10 += checksum;

  return isbn10;
}


I use this to create the Amazon affiliate links on Clair de Bulle, the famous French comics website of my wife. Yes, it's the holidays season, so I have to work for her ;-)

Comments

ben said:

Thanks for this! I translated it into Ruby if anyone's interested:

<code>

     def isbn_13_to_isbn_10(isbn13)

       isbn10 = isbn13[3,9]

       checksum = 0

       weight = 10

       isbn10.each_char do |c|

         checksum += (c.to_i * weight)

         weight -= 1

       end

       checksum = 11-(checksum % 11)

       if (checksum == 10)

         isbn10 += "X"

       elsif (checksum == 11)

         isbn10 += "0"

       else

         isbn10 += checksum.to_s

       end

       isbn10

     end

</code>

# June 16, 2008 8:24 PM

Kathe Todd said:

This is just what I was looking for, well sort of. I need to translate it into VBA for an Excel form. I came up with the following, but it keeps throwing errors...

'The ISBN-10 equals the ISBN 13 between the 4th and penultimate characters

isbn10 = OrigISBN.Substring(3, 9)

'Declare the starting values

checksum = 0

Weight = 10

'Loop through ISBN-10 adjusting checksum for each character, in order to recalculate the check digit

For i = 1 To 10

   checksum = checksum + ((Mid(isbn10, i, 1)) * Weight)

   Weight = Weight - 1

Next i

checksum = 11 - (checksum Mod 11)

If checksum = 10 Then

   isbn10 = isbn10 & "X"

   ElseIf checksum = 11 Then

       isbn10 = isbn10 & "0"

       Else: isbn10 = isbn10 & checksum

End If

isbn10TextBox.Text = isbn10

End Sub

# August 4, 2008 7:47 PM

nico said:

Hi, thanks for your function. This is the Java version :

/**

* isbn13to10Digits

* Format isbn on 13 digits to isbn on 10 digits

* @param theIsbn13 String

* @return String

* @throws EngineException

*/

public String isbn13to10Digits ( String theIsbn13 ) throws EngineException {

 // --- Test input isbn length

 if ( theIsbn13 == null || theIsbn13.trim().equalsIgnoreCase("") )

throw new EngineException("Can't format isbn 13 to 10 : null value");

 // --- Remove hyphens and spaces

 theIsbn13 = theIsbn13.replaceAll("-","").replaceAll(" ","");

 if (theIsbn13.length()!= 13)

  throw new EngineException("Can't format isbn 13 to 10 : not length 13");

 // --- Remove the useless characters

 String myIsbn10 = theIsbn13.substring(3, 9);

 int checksum = 0;

 int weight = 10;

 for ( int i = 0; i < myIsbn10.length(); i++ ){

  checksum += (int) Character.getNumericValue( myIsbn10.charAt(i) )* weight;

weight--;

 }

 checksum = 11-(checksum % 11);

 if (checksum == 10)

  myIsbn10 += "X";

 else if (checksum == 11)

  myIsbn10 += "0";

 else

  myIsbn10 += checksum;

 return myIsbn10;

}

# August 20, 2008 4:12 AM

nico said:

Hi,

there is an error on the algo at this line :

String myIsbn10 = theIsbn13.substring(3, 9);

Indeed, the second number must be 12 instead of 9 : You have to remove only the first 3 numbers and the last digit from the isbn-13.

Thanks for all.

# August 20, 2008 4:49 AM

nico said:

Another comment to complete this function. It read that ISBN-13 starting with 979 can't be converted into ISBN-10. So add into the function a line to check if the ISBN-13 we have to convert start with "979" and threw an exception if it is the case :

// --- Check if current ISBN-13 not start with 979

// ---(can't be converted to ISBN-10)

if ( theIsbn13.startsWith("979") )

  throw new EngineException("Can't format isbn 13 to 10 starting with 979");

The function should be now complete.

# August 20, 2008 4:55 AM

Michael said:

Very cool site! I have converted this to make it work with php code!

I will use this to turn a whole list of 13 digit isbn numbers to 10 digit so I can use it in an amazon search for prices.

$isbn13 = "978-988-97010-7-9";

$isbn13 = trim($isbn13);

$isbn13 = str_replace("-","",$isbn13);

$isbn13 = str_replace(" ","",$isbn13);

$isbn10 = substr($isbn13,3,9);

$checksum = 0;

$weight = 10;

$isbnCharArray = str_split($isbn10);

foreach($isbnCharArray as $char) {

$checksum += $char * $weight;

$weight--;

}

$checksum = 11-($checksum % 11);

 if ($checksum == 10)

   $isbn10 += "X";

 else if ($checksum == 11)

   $isbn10 += "0k";

 else

   $isbn10 .= $checksum;

echo $isbn10;

# August 25, 2008 1:47 AM

Stephane said:

Thanks!

Here is a visual basic version that works fine:

Public Function Isbn13to10(isbn13 As String) As String

 isbn10 = Mid(isbn13, 4, 9)

 Dim checksum

 checksum = 0

 Dim weight

 weight = 10

   For i = 1 To Len(isbn10)

      checksum = checksum + ((Mid(isbn10, i, 1)) * weight)

      weight = weight - 1

   Next i

 checksum = 11 - (checksum Mod 11)

 If checksum = 10 Then

   isbn10 = isbn10 & "X"

 Else

   If checksum = 11 Then

     isbn10 = isbn10 & "0"

   Else

       isbn10 = isbn10 & checksum

   End If

 End If

 Isbn13to10 = isbn10

End Function

# November 13, 2008 10:36 PM

Zero-Hero said:

Ok, sorry for flooding this page, but again, ignore the previous code. I promise you, this is the last time (because I've now perfected my code, and removed all bugs).

Option Strict On

Option Explicit On

Module Module1

   Dim sISBN13 As String = ""

   Dim sISBN10 As String = ""

   Function bVerifySum13(ByRef usISBN13 As String) As Boolean

       Dim iMax, iSum As Integer

       bVerifySum13 = True

       iMax = 0

       If usISBN13 Like "#############" Then

           For j As Integer = 2 To 12 Step 2

               iMax += ((Convert.ToInt32(Mid(usISBN13, (j - 1), 1))) + (3 * (Convert.ToInt32(Mid(usISBN13, j, 1)))))

           Next

           iSum = (10 - (iMax Mod 10)) Mod 10

           If iSum <> Convert.ToInt32(Mid(usISBN13, 13, 1)) Then

               bVerifySum13 = False

           End If

       Else

           bVerifySum13 = False

       End If

   End Function

   Function bVerifySum10(ByRef usISBN10 As String) As Boolean

       Dim iMax As Integer = 0

       bVerifySum10 = True

       If usISBN10 Like "##########" Or usISBN10.Length = 10 And Mid(usISBN10, 1, 9) Like "#########" And Mid(usISBN10, 10, 1) = "x" Then

           For j = 10 To 2 Step -1

               iMax += ((Convert.ToInt32(Mid(usISBN10, (10 - (j - 1)), 1))) * j)

           Next

           If Mid(usISBN10, 10, 1) <> "x" Then

               iMax += Convert.ToInt32(Mid(usISBN10, 10, 1))

           Else

               iMax += 10

           End If

           If (iMax Mod 11) <> 0 Then

               bVerifySum10 = False

           End If

       Else

           bVerifySum10 = False

       End If

   End Function

   Function sConvertN10toN13(ByRef usISBN10 As String) As String

       Dim iMax As Integer = 0

       sConvertN10toN13 = "978" + Mid(usISBN10, 1, 9)

       For j As Integer = 2 To 12 Step 2

           iMax += (Convert.ToInt32(Mid(sConvertN10toN13, (j - 1), 1))) + (3 * (Convert.ToInt32(Mid(sConvertN10toN13, j, 1))))

       Next

       sConvertN10toN13 += ((10 - (iMax Mod 10)) Mod 10).ToString

   End Function

   Function sConvertN13toN10(ByRef usISBN13 As String) As String

       Dim iMax As Integer = 0

       Dim iCount As Integer = 0

       sConvertN13toN10 = Mid(usISBN13, 4, 9)

       For j As Integer = 10 To 2 Step -1

           iMax += ((Convert.ToInt32(Mid(sConvertN13toN10, (10 - (j - 1)), 1))) * j)

       Next

       If (iMax Mod 11) <> 0 Then

           Do

               iCount += 1

           Loop Until ((iMax + iCount) Mod 11) = 0

           If iCount = 10 Then

               sConvertN13toN10 += "x"

           Else

               sConvertN13toN10 += iCount.ToString

           End If

       Else

           sConvertN13toN10 += "0"

       End If

   End Function

   Sub Main()

       Dim sInputChoice As String = ""

       Call shameless_plug()

       Call DisplayOptions()

       Do

           Call Console.Write("?: ")

           sInputChoice = Console.ReadLine()

           Select Case sInputChoice

               Case "quit"

                   End

               Case "disp"

                   Call DisplayOptions()

               Case "10"

                   Call InterfaceISBN10()

               Case "13"

                   Call InterfaceISBN13()

               Case "10to13"

                   Call InterfaceISBN10ToISBN13()

               Case "13to10"

                   Call InterfaceISBN13ToISBN10()

               Case Else

                   Call Console.WriteLine("Invalid option")

           End Select

       Loop

   End Sub

   Sub InterfaceISBN10()

       Call Console.WriteLine()

       Call Console.WriteLine("ISBN-10 Validation")

       Call Console.WriteLine("(To exit back to main menu, type 'r' and hit return)")

       Do Until sISBN10 = "r"

           Call Console.Write("?10: ")

           sISBN10 = Console.ReadLine()

           sISBN10 = sISBN10.ToLower

           If sISBN10 <> "r" And bVerifySum10(sISBN10) <> True Then

               Call Console.WriteLine("Invalid ISBN-10 number")

           ElseIf sISBN10 <> "r" And bVerifySum10(sISBN10) = True Then

               Call Console.WriteLine("Valid ISBN-10 number")

           End If

       Loop

       Call Console.WriteLine()

       Call DisplayOptions()

   End Sub

   Sub InterfaceISBN13()

       Call Console.WriteLine()

       Call Console.WriteLine("ISBN-13 Validation")

       Call Console.WriteLine("(To exit back to main menu, type 'r' and hit return)")

       Do Until sISBN13 = "r"

           Call Console.Write("?13: ")

           sISBN13 = Console.ReadLine()

           sISBN13 = sISBN13.ToLower

           If sISBN13 <> "r" And bVerifySum13(sISBN13) <> True Then

               Call Console.WriteLine("Invalid ISBN-13 number")

           ElseIf sISBN13 <> "r" And bVerifySum13(sISBN13) = True Then

               Call Console.WriteLine("Valid ISBN-13 number")

           End If

       Loop

       Call Console.WriteLine()

       Call DisplayOptions()

   End Sub

   Sub InterfaceISBN10ToISBN13()

       Call Console.WriteLine()

       Call Console.WriteLine("ISBN10 to ISBN13 conversion")

       Call Console.WriteLine("(To exit back to the main menu, type 'r' and hit return)")

       Do

           Call Console.Write("?10: ")

           sISBN10 = Console.ReadLine()

           sISBN10 = sISBN10.ToLower

           If sISBN10 <> "r" And bVerifySum10(sISBN10) <> True Then

               Call Console.WriteLine("Invalid input")

           ElseIf sISBN10 <> "r" And bVerifySum10(sISBN10) = True Then

               Call Console.WriteLine("As an ISBN13 number, this is " + sConvertN10toN13(sISBN10))

               Call System.Threading.Thread.Sleep(1200)

               Call Console.WriteLine("Verification of newly converted ISBN13 number...")

               Call System.Threading.Thread.Sleep(300)

               If bVerifySum13(sConvertN10toN13(sISBN10)) <> True Then

                   Call Console.WriteLine("Oops, it seems that this is invalid")

               Else

                   Call Console.WriteLine("Everything A-OK")

               End If

           End If

       Loop Until sISBN10 = "r"

       Call Console.WriteLine()

       Call DisplayOptions()

   End Sub

   Sub InterfaceISBN13ToISBN10()

       Call Console.WriteLine()

       Call Console.WriteLine("ISBN13 to ISBN10 conversion")

       Call Console.WriteLine("(To exit back to the main menu, type 'r' and hit return)")

       Do

           Call Console.Write("?13: ")

           sISBN13 = Console.ReadLine()

           sISBN13 = sISBN13.ToLower

           If sISBN13 <> "r" And bVerifySum13(sISBN13) <> True Then

               Call Console.WriteLine("Invalid input")

           ElseIf sISBN13 <> "r" And bVerifySum13(sISBN13) = True Then

               Call Console.WriteLine("As an ISBN10 number, this is " + sConvertN13toN10(sISBN13))

               Call System.Threading.Thread.Sleep(1200)

               Call Console.WriteLine("Verification of newly converted ISBN10 number...")

               Call System.Threading.Thread.Sleep(300)

               If bVerifySum10(sConvertN13toN10(sISBN13)) <> True Then

                   Call Console.WriteLine("Oops, it seems that this is invalid")

               Else

                   Call Console.WriteLine("Everything A-OK")

               End If

           End If

       Loop Until sISBN13 = "r"

       Call Console.WriteLine()

       Call DisplayOptions()

   End Sub

   Sub DisplayOptions()

       Call Console.WriteLine("Options:")

       Call Console.WriteLine("10 - ISBN10 validation")

       Call Console.WriteLine("13 - ISBN13 validation")

       Call Console.WriteLine("10to13 - ISBN10 to ISBN13 conversion")

       Call Console.WriteLine("13to10 - ISBN13 to ISBN10 conversion")

       Call Console.WriteLine("disp - display these options")

       Call Console.WriteLine("quit - exit this program")

   End Sub

   Sub shameless_plug()

       Call Console.WriteLine("Z-130 version pi")

       Call Console.WriteLine("Written by Zero-Hero")

       Call Console.WriteLine("License: Public Domain")

       Call Console.WriteLine()

       Call Console.WriteLine("This program does the following:")

       Call Console.WriteLine("1) Convert (either way) between ISBN10 and ISBN13, at your choice")

       Call Console.WriteLine("2) Check the validity of either an ISBN10 or ISBN13 number, at your choice")

       Call Console.WriteLine()

       Call Console.WriteLine("This program will NOT do the following:")

       Call Console.WriteLine("1) Make girls like you")

       Call Console.WriteLine("2) Make men like you")

       Call Console.WriteLine()

       Call Console.Write("Press enter to continue")

       Call Console.ReadLine()

       Call Console.WriteLine()

   End Sub

End Module

# December 1, 2008 5:44 PM

Zero-Hero said:

Ok, people, if you read in the source code of my program that it is called "Z-130", note that I have changed my mind. Z-130 is the name of a particular Samsung cellphone and I don't want to infringe on any trademarks, so I will be using the name "AK3N" instead.

# December 1, 2008 6:18 PM

Philip Kimmey said:

There is a slight error in the code, which will cause problems for ISBNs with Xs on the end.

In the PHP on about Line 13

$isbn10 += "X";

Should be something like

$isbn10 = $isbn10 . "X";

Because PHP appends with '.' not '+'.

The line below that also looks suspicious, the one with the 0, although I haven't had any problems caused by it, I'm going to change it in my code.

Anyway, if anyone is having strange errors, hopefully the function below will help solve it:

function isbn13_to_isbn10($isbn13) {

$isbn13 = trim($isbn13);

$isbn13 = str_replace("-","",$isbn13);

$isbn13 = str_replace(" ","",$isbn13);

$isbn10 = substr($isbn13,3,9);

$checksum = 0;

$weight = 10;

$isbnCharArray = str_split($isbn10);

foreach($isbnCharArray as $char) {

$checksum += $char * $weight;

$weight--;

}

$checksum = 11-($checksum % 11);

if ($checksum == 10) { $isbn10 = $isbn10 . "X"; }

else if ($checksum == 11) { $isbn10 += "0k"; }

else $isbn10 .= $checksum;

return $isbn10;

}

# December 9, 2008 12:37 AM

Iwan Djunaidy said:

Thanks for the code examples.

Actually Amazon does support ISBN-13, but tagged as EAN (if you parse AWS XML response).

And ISBN still means ISBN-10.

# December 16, 2008 11:29 AM

Groovy On Grails Notes / ISBN13 to ISBN10 groovy??? said:

Pingback from  Groovy On Grails Notes / ISBN13 to ISBN10 groovy???

# July 19, 2009 7:18 AM
Leave a Comment

(required) 

(required) 

(optional)

(required)