LinuxQuestions.org
View the Most Wanted LQ Wiki articles.
Go Back   LinuxQuestions.org > Forums > Linux Forums > Linux - General
User Name
Password
Linux - General This Linux forum is for general Linux questions and discussion.
If it is Linux Related and doesn't seem to fit in any other forum then this is the place.

Notices

Reply
 
Search this Thread
Old 02-15-2009, 04:38 PM   #1
hgate73
LQ Newbie
 
Registered: Sep 2008
Posts: 17

Rep: Reputation: 0
Nice script to convert numbers between bases (bin/dec/oct/hex)


I had to write this script for an assignment, and it took me hours of pulling out my hair to figure it out (I'm new to shell scripting), so I thought I'd post it. I know it's probably not the most efficient way to do it, since a CASE would probably be better, but it works for me.

Basically it converts numbers of one base (I.E. hex numbers like 2F) to another base (I.E. binary or decimal or octal).

Let me know if you like it, or if there's a way to improve it.

Code:
#!/bin/bash
# Title:        bConvert.sh
# Purpose:      Converts numbers from one base to another
# Requiremetns: BASH shell
# Author:       hgate73 (linuxquestions.org)

# Structure:
# $1 is base of number being converted (-d, -h, -b, -o)
# $2 is number to convert
# $3 is base of number to convert to  (-d, -h, -b, -o)
# Example: ./bConvert.sh -d 3 -b    will convert the decimal (-d for DECIMAL) number 3 to binary (-b for BINARY). It should result in 11

# This is to make sure the input value is in upper-case if it is a letter
number=$( echo "$2" | tr -s '[:lower:]' '[:upper:]' )

# Error checking
if [ $# = 0 ]; then echo "You didn't specify any arguments."; exit; fi

##################
# 1. Set IN type #
##################
if [ "$1" = "-b" ]; then    #bin/2
    inType='2'
elif [ "$1" = "-o" ]; then    #oct/8
    inType=8   
elif [ "$1" = "-d" ]; then    #dec/10
    inType=10
elif [ "$1" = "-h" ]; then    #hex/16
    inType=16
fi

###################
# 2. Set OUT type #
###################
if [ "$3" = "-b" ]; then    #bin/2
    outType='2'
elif [ "$3" = "-o" ]; then    #oct/8
    outType=8   
elif [ "$3" = "-d" ]; then    #dec/10
    outType='10'
elif [ "$3" = "-h" ]; then    #hex/16
    outType=16
fi

#########################
# 3. Perform conversion #
#########################
result=$(echo "obase=$outType;ibase=$inType;$number" | bc); echo $result

Last edited by hgate73; 02-15-2009 at 04:40 PM.
 
Old 02-15-2009, 05:43 PM   #2
i92guboj
Gentoo support team
 
Registered: May 2008
Location: Lucena, Córdoba (Spain)
Distribution: Gentoo
Posts: 4,040

Rep: Reputation: 373Reputation: 373Reputation: 373Reputation: 373
This is the way I'd do it:

Code:
#!/bin/bash

function die () {
  echo "$1"
  exit 1
  # it's better to exit with an error code other than zero,
  # this way, external programs can know whether this succeeded
  # or not :)
}
 
function convert() {
  number=$( echo "$3" | tr -s '[:lower:]' '[:upper:]' )
  result=$(echo "obase=$2;ibase=$1;$number" | bc)
  if [ ! "$?" == "0" ]; then
    die "bc error: wrong values."
  fi
  echo "Original number in base $1: $number"
  echo "Converted number in base $2: $result"
}
 
# Error checking
if [ $# = 0 ]; then die "You didn't specify any arguments."; fi

# Defaults
inType=10
outType=16

while [ -n "$1" ]; do
  case "$1" in
    -i|--input-base)
      if [ -n "$2" ]; then
        inType="$2"
      else
        die "  $1 requires an aditional parameter."
      fi
      shift; shift;
      ;;
    -o|--output-base)
      if [ -n "$2" ]; then
        outType="$2"
      else
        die "  $1 requires an aditional parameter."
      fi
      shift; shift;
      ;;
    *)
      convert $inType $outType $1
      shift;
      ;;
  esac
done
Case along with shift let you handle the arguments in a smarter and more flexible way (you can use -i and -o on any order, as long as the following argument is the base). Note that it will also convert as many numbers as desired on a single run:

Code:
bconvert -o 3 108762345243 42352453 524352453
Original number in base 10: 108762345243
Converted number in base 3: 101101201211112121020000
Original number in base 10: 42352453
Converted number in base 3: 2221200201122101
Original number in base 10: 524352453
Converted number in base 3: 1100112122212100020
It's better to use different argument names for different arguments. Your original design is prone to confusion in that regard because the arguments to determine inType and outType are named the same. This script should handle any base, and not just 8, 10 and 16. It also has defaults for inType and outType so you don't forcingly have to specify none.

What could be enhanced? Well, the error handling could be better. Also you could add a -h|--help clause in the case statement. The help text could be designed as a function (you already have two examples in that code), a function that should be called either when you use -h or --help or when you invoke the program without arguments. Designing it as a function let's you call it from many places without having to duplicate the code. You could as well add -idec, -ihex, -ibin, -ioct, -ooct, -odec, -ohex, -obin parameters that would be shorthands for these common bases.

This is a quick adaptation so it might have some flaws that I haven't yet considered.

EDIT: fixed.

Last edited by i92guboj; 02-15-2009 at 06:02 PM.
 
Old 02-16-2009, 03:38 PM   #3
hgate73
LQ Newbie
 
Registered: Sep 2008
Posts: 17

Original Poster
Rep: Reputation: 0
This is good information, thanks a lot. I knew there had to be a way to do it with CASE statements, but I haven't covered them yet and I don't know how to use them. Thanks for the great example.
 
Old 02-17-2009, 03:19 AM   #4
H_TeXMeX_H
Guru
 
Registered: Oct 2005
Location: $RANDOM
Distribution: slackware64
Posts: 12,928
Blog Entries: 2

Rep: Reputation: 1269Reputation: 1269Reputation: 1269Reputation: 1269Reputation: 1269Reputation: 1269Reputation: 1269Reputation: 1269Reputation: 1269
Sorry, but I'd do this in C not bash.
 
Old 02-17-2009, 03:51 AM   #5
nx5000
Senior Member
 
Registered: Sep 2005
Location: Out
Posts: 3,307

Rep: Reputation: 52
Another way
Code:
#!/usr/bin/perl
#This program is freeware, after 15 days, you have to purchase it ;-)
print unpack("$ARGV[2]*",pack("$ARGV[0]*",$ARGV[1])) . "\n"
./script C 3 B
00000011

./script B 00001111 H
0f

floats to native ieee representation:

./script f 1.1 H
cdcc8c3f
 
  


Reply

Tags
base, binary, converter


Thread Tools Search this Thread
Search this Thread:

Advanced Search

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
How Can I convert Hex to Binary in a perl script telecom_is_me Programming 18 10-11-2010 04:34 PM
can any one list all the methods for converting dec->Hex telnet_ping Programming 2 09-13-2007 11:41 PM
dec to hex ewt3y Linux - General 2 08-16-2005 12:01 PM
gnome-calculator - converting between numeric bases (eg hex to binary) jht2k Linux - General 2 07-01-2005 09:12 AM
Convert from hex to dec Ephracis Programming 3 05-30-2005 10:42 AM


All times are GMT -5. The time now is 09:33 PM.

Main Menu
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
identi.ca: @linuxquestions
Facebook: linuxquestions Google+: linuxquestions
Open Source Consulting | Domain Registration