Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Comparing version number strings (major, minor, revision, beta)

I have an application that communicates with the firmware of a device. As there are changes to the firmware, it is versioned with the format {major}.{minor}.{revision}[beta[{beta}]]. To give you a few examples, the current version is 0.4.7beta which will be followed by 0.4.7beta2 and occasionally 0.4.7, followed by 0.4.8beta. The versioning format of the firmware is unfortunately not under my control, so I can not change it.

I need a way of comparing firmwares with each other. Basically, I need a function

boolean isFirmwareNewer(String testFW, String baseFW);

What I did so far was to convert this format to a simple int. So 0.4.7beta2 will become 00040702 (2 digits for each level). The problem is, that

  1. My code is difficult to read (>40 lines and 3 methods)
  2. I am sure, there is a elegant solution to this (maybe using regex?)
  3. I want to have a wildcard 0.0.0 which is newer by definition
  4. This handles the beta versions incorrect (0.4.7beta2 is not newer than 0.4.7). That is easy to account for (if (testFW.contains("beta")) testFWValue -= 100;, but it's not really elegant as well.

How do you guys do this normally (or how would you do it)?

If you want, I can attach the code I am currently working with, but as I said, it's >40 lines of code and not really readable (which is the reason why I am looking for a better way to do this).

like image 635
brimborium Avatar asked Jul 16 '12 09:07

brimborium


People also ask

How do I compare two versions of numbers?

To compare version numbers, compare their revisions in left-to-right order. Revisions are compared using their integer value ignoring any leading zeros. This means that revisions 1 and 001 are considered equal. If a version number does not specify a revision at an index, then treat the revision as 0 .

How do I compare string versions?

compareVersions(String v1, String v2) compares two version strings. It returns 0 if the versions are equal, 1 if version v1 is before version v2, -1 if version v1 is after version v2, -2 if version format is invalid.

What is major and minor version?

Version numbers usually consist of three numbers separated by dots. For example: 1.2. 3 These numbers have names. The leftmost number (1) is called the major version. The middle number (2) is called the minor version.

What is major minor and patch version?

MAJOR version increment indicates incompatible API changes. MINOR version increment indicates addition of functionality in a backwards-compatible manner. PATCH version increment indicates backwards-compatible bug fixes.


1 Answers

Here's one suggestion:

static int[] getVersionNumbers(String ver) {
    Matcher m = Pattern.compile("(\\d+)\\.(\\d+)\\.(\\d+)(beta(\\d*))?")
                       .matcher(ver);
    if (!m.matches())
        throw new IllegalArgumentException("Malformed FW version");

    return new int[] { Integer.parseInt(m.group(1)),  // major
            Integer.parseInt(m.group(2)),             // minor
            Integer.parseInt(m.group(3)),             // rev.
            m.group(4) == null ? Integer.MAX_VALUE    // no beta suffix
                    : m.group(5).isEmpty() ? 1        // "beta"
                    : Integer.parseInt(m.group(5))    // "beta3"
    };
}

static boolean isFirmwareNewer(String testFW, String baseFW) {

    int[] testVer = getVersionNumbers(testFW);
    int[] baseVer = getVersionNumbers(baseFW);

    for (int i = 0; i < testVer.length; i++)
        if (testVer[i] != baseVer[i])
            return testVer[i] > baseVer[i];

    return true;
}

It uses a little trick and translates the beta-part as follows:

  • "" (no beta suffix) → Beta MAX_INT
  • "beta" → Beta 1 (since it preceeds "beta2")
  • "betaX" → Beta X

Note that it return true if both versions are identical.

like image 159
aioobe Avatar answered Oct 22 '22 12:10

aioobe