Skip to main content
Home
plus.maths.org

Secondary menu

  • My list
  • About Plus
  • Sponsors
  • Subscribe
  • Contact Us
  • Log in
  • Main navigation

  • Home
  • Articles
  • Collections
  • Podcasts
  • Maths in a minute
  • Puzzles
  • Videos
  • Topics and tags
  • For

    • cat icon
      Curiosity
    • newspaper icon
      Media
    • graduation icon
      Education
    • briefcase icon
      Policy

    Popular topics and tags

    Shapes

    • Geometry
    • Vectors and matrices
    • Topology
    • Networks and graph theory
    • Fractals

    Numbers

    • Number theory
    • Arithmetic
    • Prime numbers
    • Fermat's last theorem
    • Cryptography

    Computing and information

    • Quantum computing
    • Complexity
    • Information theory
    • Artificial intelligence and machine learning
    • Algorithm

    Data and probability

    • Statistics
    • Probability and uncertainty
    • Randomness

    Abstract structures

    • Symmetry
    • Algebra and group theory
    • Vectors and matrices

    Physics

    • Fluid dynamics
    • Quantum physics
    • General relativity, gravity and black holes
    • Entropy and thermodynamics
    • String theory and quantum gravity

    Arts, humanities and sport

    • History and philosophy of mathematics
    • Art and Music
    • Language
    • Sport

    Logic, proof and strategy

    • Logic
    • Proof
    • Game theory

    Calculus and analysis

    • Differential equations
    • Calculus

    Towards applications

    • Mathematical modelling
    • Dynamical systems and Chaos

    Applications

    • Medicine and health
    • Epidemiology
    • Biology
    • Economics and finance
    • Engineering and architecture
    • Weather forecasting
    • Climate change

    Understanding of mathematics

    • Public understanding of mathematics
    • Education

    Get your maths quickly

    • Maths in a minute

    Main menu

  • Home
  • Articles
  • Collections
  • Podcasts
  • Maths in a minute
  • Puzzles
  • Videos
  • Topics and tags
  • Audiences

    • cat icon
      Curiosity
    • newspaper icon
      Media
    • graduation icon
      Education
    • briefcase icon
      Policy

    Secondary menu

  • My list
  • About Plus
  • Sponsors
  • Subscribe
  • Contact Us
  • Log in
  • Podcast 8, April 2008: Codes and codebreaking - the Enigma machine

    18 April, 2008

    The Enigma machine was once considered unbreakable, and the cracking of the "unbreakable code" by the allies changed the course of World War 2. This week, Plus talks to Nadia Baker from the Enigma Project about the history of codes and code-breaking, why the Enigma machine was considered unbreakable, the mathematics behind codes, and how it was finally cracked. The Enigma Project travels all over the United Kingdom and abroad, visiting over 100 schools and organisations, reaching over 12,000 people of all ages every year.

    • Log in or register to post comments

    Anonymous

    3 August 2010

    Permalink

    // INDENTATION HAS NOT BEEN PRESERVED BY THIS WEB SITE,,, sorry about that.. .

    // Dennis Bednar 2010-08-03.
    //
    // This code is related to Enigma plugboard of Enigma cryptographic machine used in World War 2.
    // There are 26 plugs labelled A-Z, in the plugboard.
    // The "plug" for each letter actually has two sockets, and there are two male pins at end of each wire.
    //
    // A wire can be between any two *different* letters, which causes the pair of letters to be swapped.
    // Hence if there is a wire between A and K, then input A converts into output K,
    // and input K converts into output A. (IE, A <-> K).
    //
    // To compile and run this code:
    //
    // contents of doit.cmd file:
    // rem compile and run Main.java
    // del Main.class
    // \jdk1.5.0_08\bin\javac.exe Main.java
    // \jdk1.5.0_08\bin\java.exe Main
    //
    // Then just run doit.cmd.
    // ====================================================

    import java.math.BigInteger; // for big integers arbitrarily large

    public class Main
    {
    public static void main( String argv [] )
    {

    // TEST CODE IS commented out.

    // testFactorials();

    // testCommas();

    work();
    }

    // Unit Test Code
    // compute n! for n=1..10

    public static void testFactorials()
    {
    System.out.println( "=== BEG testFactorials ===" );
    for (int i = 1; i < 10; ++i)
    {
    // convert into into String, so we can use BigInteger(String) constructor
    String strNum = new Integer(i).toString();

    BigInteger bi = new BigInteger( strNum );
    BigInteger result = factorial( bi );
    System.out.println( strNum + "!=" + result );
    }
    System.out.println( "=== END testFactorials ===" );
    }

    // Unit Test Code
    // try putting in comma's with decimal digits strings that are 1..MAX_PLACES length
    // starting with "1", "12", "123", "1234", ... "123456789", "1234567890", ...
    // we expect to convert "1234" into "1,234", to add commas in that number.

    public static void testCommas()
    {
    final int NUM_PLACES = 25; // a constant, max nr of decicmal positions

    System.out.println( "=== BEG testCommas ===" );
    // try num=1, "12", "123", ... "123456789", "1234567890", "12345678901"
    String num = "";

    // used to figure out which digit to grab next
    String digits = "0123456789";

    // try input number strings with values of "1", "12", "123", "1234",
    // and so forth

    for (int i = 1; i <= NUM_PLACES; ++i)
    {
    int pos = i%10;
    num += digits.substring( pos, pos+1 );
    String result = addCommas (num );
    System.out.println( "IN: " + num + " OUT: " + result );
    }
    System.out.println( "=== END testCommas ===" );

    }

    // see also:
    // http://www.codesandciphers.co.uk/enigma/steckercount.htm
    //
    // More abstractly: the number of ways of choosing m pairs out of n objects is:
    //
    // n! /((n-2m)! m! 2m)
    //
    // If you want to convince yourself of this formula you might like to check that there are:
    //
    // 3 different ways of putting 2 pairs of wire into 4 plugboard sockets
    // 15 different ways of putting 3 pairs of wire into 6 plugboard sockets.
    // From this formula we can find out something which often surprises people, which is that the number of possible plugboard pairings is greatest for 11 pairs, and then decreases:
    //
    // EXPECTED OUTPUT from this function, based on above "see also" HTML link:
    //
    // 1 pair: 325
    // 2 pairs: 44.850
    // 3 pairs: 3,453,450
    // 4 pairs: 164,038,875
    // 5 pairs: 5,019,589,575
    // 6 pairs: 100,391,791,500
    // 7 pairs: 1,305,093,289,500
    // 8 pairs: 10,767.019,638,375
    // 9 pairs: 58,835.098,191,875
    // 10 pairs: 150,738,274,937,250
    // 11 pairs: 205,552,193,096,250
    // 12 pairs: 102,776,096,548,125
    // 13 pairs: 7,905,853,580,625
    //
    //

    public static void work()
    {
    System.out.println( "=== Number of combinations of m wires in Enigma plugboard having 26 letters ===" );

    BigInteger numWires = BigInteger.ONE;

    final BigInteger NUM_PLUGS = new BigInteger("26");

    // try 1..13 wires in a plugboard of 26 letters
    //
    // NB: I once tried 14 instead of 13, and verified that we blew up with
    // IllegalArgumentExceptioni when trying to call factorial(-2).

    for( int i = 1; i <= 13; ++i)
    {
    String strPair = null;
    BigInteger combinations = numPairs( NUM_PLUGS, numWires );
    if (i == 1)
    strPair = "pair";
    else
    strPair = "pairs";

    // before we could rely on addComma() method, we print both without *and* with commas
    // System.out.println( numWires + " " + strPair + ": " + combinations + " (" + addCommas(combinations.toString() ) + ")" );

    // i pair(s): combinations_with_commas

    System.out.println( numWires + " " + strPair + ": " + addCommas(combinations.toString() ) );
    numWires = numWires.add( BigInteger.ONE );
    }
    System.out.println( "=== DONE ===" );

    }

    // return number of pairs of m objects from n total objects
    //
    // More abstractly: the number of ways of choosing m pairs out of n objects is:

    // n! /((n-2m)! m! 2^m)
    public static BigInteger numPairs( BigInteger n, BigInteger m )
    {
    final BigInteger TWO = new BigInteger( "2" );

    BigInteger numerator = factorial( n );
    BigInteger div1 = factorial( n.subtract( m.multiply( TWO )) ); // (n-2m) !
    BigInteger div2 = factorial( m ); // m!

    int mi = m.intValue(); // cannot do pow(BigInteger), must do pow(int)
    BigInteger div3 = TWO.pow( mi ); // 2^m

    BigInteger divisor = div1.multiply(div2.multiply(div3)); // div1*div2*div3

    BigInteger result = numerator.divide( divisor );
    return result;
    }

    // return n!, or "n factorial".
    // 0! = 1
    // 1! = 1
    // 2! = 2*1
    // 3! = 3*2*1
    // 4! = 4*3*2*1
    // ...
    // n! = n * (n-1) * (n-2) * (n-3) * ... * 3 * 2 * 1
    /**
    * @return n!
    * @throws IllegalArgumentException if n < 0.
    */

    public static BigInteger factorial( BigInteger n )
    {
    // if n < 0 (ie, a netative number, then this is illegal)

    if (n.compareTo( BigInteger.ZERO ) < 0)
    throw new IllegalArgumentException( "factorial(" + n.toString() + ") attempted: you cannot use negative number" );

    if (n.equals(BigInteger.ZERO))
    return BigInteger.ONE;
    if (n.equals(BigInteger.ONE))
    return BigInteger.ONE;
    BigInteger prod = BigInteger.ONE;

    // prod = n * (n-1) ... * 3 * 2

    while (! n.equals(BigInteger.ONE))
    {
    prod = prod.multiply(n); // prod = prod * n
    n = n.subtract( BigInteger.ONE ); // n = n-1
    }

    return prod;
    }

    // add comma's to a decimal integer
    // "" -> ""
    // "1" -> "1"
    // "12" -> "12"
    // "123" -> "123"
    // "1234" -> "1,234"
    // "12345" -> "12,345"
    // "123456 -> "123,456"

    public static String addCommas( String number )
    {
    if (number.indexOf(".") != -1)
    throw new IllegalArgumentException( "illegal decimal point found:" + number );

    // TBD: maybe should check that only digits 0-9 are passed in number ??

    // 3 or less digits is unchanged
    if (number.length() <= 3)
    return number;

    // find index where first comma belongs

    // find len of initial digits ( 4 -> 1, 5 -> 2, 6 -> 3)
    int prefixLen = number.length() % 3;
    if (prefixLen == 0)
    prefixLen = 3;

    int begInx = 0;
    int endInx = prefixLen;

    // put comma AFTER each group (not now)
    String result = number.substring( begInx, endInx );
    int remLength = number.length() - prefixLen;

    // after first comma
    begInx += prefixLen;
    endInx += 3;

    // remLen is now a multiple of 3, and we
    // take 3 digits at a time, putting a comma in front of each 3 digits.

    for (; remLength > 0; remLength -= 3)
    {
    // concatenate "," and next 3 digits
    result += ( "," + number.substring( begInx, endInx ) );

    // move to the next group of 3 digits
    begInx += 3;
    endInx += 3;
    }

    return result;
    }
    }

    • Log in or register to post comments

    Anonymous

    2 March 2011

    Permalink

    instead of 58,835.098,191,875 for 9 pairs, should stay 53,835.098,191,875

    • Log in or register to post comments
    You can listen to the podcast using the player above, and you can listen and subscribe to our podcast through Apple Podcasts, Spotify and through most other podcast providers via podbean.
    University of Cambridge logo

    Plus is part of the family of activities in the Millennium Mathematics Project.
    Copyright © 1997 - 2025. University of Cambridge. All rights reserved.

    Terms