Binary to Hexadecimal

1

Convert a binary number (of any size) into a hexadecimal number.

Input
A POSITIVE binary number with just the 0s and 1s. A valid input will always match the following regex: [0-1]+. If the input is not a valid binary number, that is, anything not matching this regex, the output should be 0 or the program should exit, or error. The output does not need the leading 0x nor does it need to be capitalized.

Output
The binary number converted to hexadecimal.

Winning
Original Code-Golf Rules, Lowest amount of bytes.

Examples

IN: [101]
OUT: [0x5] OR [5]

IN: [10000000010100100000]
OUT: [0x80520] OR [80520]

IN: [1010101]
OUT: [0x55] OR [55]

IN: [1111111111111111]
OUT: [0xFFFF] OR [FFFF] OR [0xffff] OR [ffff]

IN: [1012101]
OUT: [0]

IN: [a]
OUT: [0]

IN: [-1010101]
OUT: [0]

IN: [abcdef]
OUT: [0]

IN: [2]
OUT: [0]

Hashim Kayani

Posted 2017-08-27T20:07:14.940

Reputation: 327

12Boo-urns to input validation! – Shaggy – 2017-08-27T20:19:54.737

2Can we exit if the input isn't valid binary? – caird coinheringaahing – 2017-08-27T20:20:59.357

@cairdcoinheringaahing Yes – Hashim Kayani – 2017-08-27T20:39:41.547

2This should be popularity contest or something, not code golf. – Titus – 2017-08-27T21:11:38.010

@Titus popularity-contest would be a lot better – dv02 – 2017-08-27T21:24:57.267

6@DirtyDev Popularity contest would NOT better. – Level River St – 2017-08-27T21:29:32.507

...note how many answers do not conform to the input validation requirements - this is one of the reasons to just not have such restrictions in code-golf. – Jonathan Allan – 2017-08-27T23:11:48.047

11You could shave one byte off your regex: [01]+ – martin – 2017-08-28T02:10:37.063

1@Titus This would be closed instantly as a pop con. – Dennis – 2017-08-28T05:45:24.373

75 hours was far too quick to an accept a solution, especially one that does not meet the specs on invalid input. – Shaggy – 2017-08-28T09:32:20.433

In tcl, these regexp is not enough to exclude -1010101, may be because the - is the parameter indicator, example: regexp -expanded ... – sergiol – 2017-11-20T00:03:44.573

I wish there was a "boring" close-vote reason, the "input validation" part of this spec really ruins the challenge. – MD XF – 2017-12-23T04:16:50.397

Answers

3

MY, 8 6 5 bytes

⍞PrH↵

Try it online!

How?

  • line of raw input
  • P basify
  • r convert from binary
  • H convert to hex
  • output

Errors if input isn't correct.

Zacharý

Posted 2017-08-27T20:07:14.940

Reputation: 5 710

1

Java, 126 119 117 110 104 Bytes

Thanks to Jakob and Zacharý

class A{public static void main(String[]s){System.out.print(Long.toHexString(Long.parseLong(s[0],2)));}}

Expanded:

class A
{
    public static void main(String[] s)
    {
        System.out.print(Long.toHexString(Long.parseLong(s[0], 2)));
    }
}

Hashim Kayani

Posted 2017-08-27T20:07:14.940

Reputation: 327

1

You can shorten with a function like this: https://codegolf.stackexchange.com/a/140570/46313

– geokavel – 2017-08-27T20:18:04.853

Or, if you want to stick with Java 7, you can submit a method definition, e.g. int f(String s){ ... }. Also, you can save bytes by using Long.toHexString and Long.parseLong. – Jakob – 2017-08-27T20:32:27.603

Also, remove the space after String[]. – Zacharý – 2017-08-27T20:32:57.013

@Downvoter: Why? – Shaggy – 2017-08-27T21:30:13.247

As @geokavel mentioned, you can use a Java 8 lambda to shorten your code, since you didn't specify in your challenge you should have a full program, and the default here on PPCG is "program or function/lambda": s->Long.toHexString(Long.parseLong(s,2)). But, if you want to stick with a full program, you can also shorten it with Java 8 by replacing class A{public static void main(String[]a){ with interface A{static void main(String[]a){. – Kevin Cruijssen – 2017-09-01T13:26:35.343

1

PHP, 25+1 bytes

<?=dechex(bindec($argn));

Run as pipe with -F.

or 27+1 bytes: (-R)

printf("%x",bindec($argn));

or 28+1 bytes: (-F)

<?=base_convert($argn,2,16);

or 30+1 bytes: (-R)

eval("printf('%x',0b$argn);");

Titus

Posted 2017-08-27T20:07:14.940

Reputation: 13 814

1

Retina, 72 70 bytes

A`[^01]
T`d`l`.(?!(....)*$)
T`d`23`b\d
T`d`4-7`b.\d
T`d`89L`b..\d
a|b

Try it online! Output is blank on error. Edit: Saved 2 bytes thanks to @PunPun1000. Explanation:

A`[^01]

Delete non-binary input.

T`d`l`.(?!(....)*$)

Convert all digits not in the correct position to as and bs instead.

T`d`23`b\d

Add 2 to digits that follow a b.

T`d`4-7`b.\d

Add 4 to digits two after a b.

T`d`89L`b..\d

Add 8 to digits three after a b.

a|b

The as and bs have done their job and can be deleted.

Neil

Posted 2017-08-27T20:07:14.940

Reputation: 95 035

89A-F can be replaced with 89L assuming I'm reading your explanation correctly – PunPun1000 – 2017-08-28T13:55:46.880

@PunPun1000 Thanks for reminding me; I knew there was something I'd overlooked. – Neil – 2017-08-28T14:48:47.047

1

C, 168 bytes

i,l,k,n;f(char*s){char*o=malloc(l=strlen(s));for(i=n=0;i<l;n+=k<<i++)if((k=s[l-i-1]-48)&&k-1)return 0;for(i=o[--l]=0;n;n/=16)k=n%16,o[l-++i]=k>9?k+55:k+48;puts(o+l-i);}

Try it online!

Unrolled:

i,l,k,n;
f(char *s)
{
    // Allocate a string for the hexadecimal digits.
    // The number of digits in the hex number is
    // sure to be less or equal to that of binary.
    char *o = malloc(l=strlen(s));

    // Convert binary to decimal.
    // The function returns zero without printing
    // anything if there are extraneous characters.
    for (i=n=0; i<l; n+=k<<i++)
        if ((k=s[l-i-1]-48) && k-1) return 0;

    // Convert decimal to hexadecimal.
    for (i=o[--l]=0; n; n/=16)
        k = n%16, o[l-++i] = k>9 ? k+55 : k+48;

    // Print the number in hexadecimal.
    puts(o+l-i);
}

Steadybox

Posted 2017-08-27T20:07:14.940

Reputation: 15 798

1

CJam, 17 bytes

{2bGb{_9>'70?+}%}

Function that takes an array of bits as input.

Test Version

{
2b     e# Convert from base-2 to base-10.
Gb     e# Convert from base-10 to base-16.
{      e# For each digit in the hex version...
_      e# Duplicate it.
9>     e# Check if it's greater than 9.
'70?   e# If it is, add a '7' (char) to the stack. If not, add a 0 (int).
 +     e# Add the new item to the digit. Int + char => Increment char's ASCII value by int. (e.g '7' + 10 = 'A')
}%
}

If necessary, here's a version that checks for invalid input (29 bytes):

{_2,|$2,=1W?*2bGb{_9>'70?+}%}

Test Version

It outputs 0 for an empty array and throws an exception for all other invalid input.

How validation works....

{
_2,|$  e# Get Logical OR of input array and [0,1], sorted.
2,=    e# Does that equal [0,1]?
1W?    e# If the arrays are equal add 1 to the stack, if not add -1.
*      e# Repeat the input as many times as the number just added to the stack. 
       e# If the number is 1, the input is unchanged.
       e# If it's -1 you get an error for an invalid number of repetitions.
...

geokavel

Posted 2017-08-27T20:07:14.940

Reputation: 6 352

Does not exit, error or yield 0 for all invalid inputs.

– Jonathan Allan – 2017-08-27T23:16:39.613

@Jon I did it this way because of the comments on caird's Osabie answer. I guess it's not clear what "error" as a verb means. – geokavel – 2017-08-27T23:40:51.727

There would be no point in specifying that the program should "do something unexpected given invalid input" as there is no valid output for invalid input, so I think "should error" is pretty clear (although as I commented under the OP I think input validation should really be avoided). – Jonathan Allan – 2017-08-27T23:43:53.523

1

6502 machine code (C64), 100 bytes

00 C0 20 FD AE 20 9E AD 20 A3 B6 8D 1C C0 A0 00 84 FB 84 FC 29 03 AA D0 16 A2
04 A4 FB C0 FF D0 0E A4 FC A9 00 99 62 C0 A0 C0 A9 62 4C 1E AB A9 00 85 FE CA
30 1B 06 FE A4 FB E6 FB B1 22 C9 30 F0 F1 C9 31 F0 03 4C 99 AD A5 FE 09 01 85
FE D0 E2 A9 30 05 FE C9 3A 30 02 69 06 A4 FC 99 62 C0 E6 FC D0 B5

Online demo

Usage: sys49152,"[input]", where [input] is your binary string, e.g. sys49152,"10000000010100100000".

Important: When the program was loaded from disk (like in the online demo!), issue a new command first! This is because loading the program fiddles with some BASIC pointers and the machine thinks there's no RAM left for a string...


Explanation (commented disassembly listing):

00 C0       .WORD $C000         ; load address
20 FD AE    JSR $AEFD           ; check for comma
20 9E AD    JSR $AD9E           ; evaluate expression
20 A3 B6    JSR $B6A3           ; get string from expression
8D 1C C0    STA $C01C           ; store input string length for CPY instruction
A0 00       LDY #$00            ; initialize counters to 0:
84 FB       STY $FB             ;    read counter
84 FC       STY $FC             ;    write counter
29 03       AND #$03            ; number of bits in first incomplete nibble
AA          TAX                 ;  -> to X register
D0 16       BNE .nibble         ; branch to nibble decoding if not 0
 .mainloop:
A2 04       LDX #$04            ; from here on 4 bits per nibble
A4 FB       LDY $FB             ; load read counter to Y
C0 04       CPY #$FF            ; compare with input length (argument modified)
D0 0E       BNE .nibble         ; not yet done -> branch to nibble decoding
A4 FC       LDY $FC             ; load store counter
A9 00       LDA #$00            ; write NUL terminator 
99 62 C0    STA .outbuf,Y       ; to output string
A0 C0       LDY #$C0            ; load address of
A9 62       LDA #$62            ; output string
4C 1E AB    JMP $AB1E           ; and jump to string output routine
 .nibble:
A9 00       LDA #$00            ; initialize value of nibble to zero
85 FE       STA $FE             ; store to temporary variable
 .nibbleloop:
CA          DEX                 ; decrement number of bits
30 1B       BMI .nibbleout      ; no bits left -> prepare for output
06 FE       ASL $FE             ; shift temporary variable left
A4 FB       LDY $FB             ; load read counter to Y
E6 FB       INC $FB             ; increment read counter
B1 22       LDA ($22),Y         ; load next input character
C9 30       CMP #$30            ; compare with '0'
F0 F1       BEQ .nibbleloop     ; if equal, handle next bit
C9 31       CMP #$31            ; compare with '1'
F0 03       BEQ .nibbleadd      ; if equal, add that bit
4C 99 AD    JMP $AD99           ; neither '0' or '1' -> type mismatch error
 .nibbleadd:
A5 FE       LDA $FE             ; load temporary variable
09 01       ORA #$01            ; set lowest bit
85 FE       STA $FE             ; store temporary variable
D0 E2       BNE .nibbleloop     ; handle next bit
 .nibbleout:
A9 30       LDA #$30            ; load character '0'
05 FE       ORA $FE             ; combine with value from temporary variable
C9 3A       CMP #$3A            ; result smaller than 0x39 ('9') ?
30 02       BMI .nibblestore    ; then store that
69 06       ADC #$06            ; otherwise add offset to get in range 'a'-'f'
 .nibblestore:
A4 FC       LDY $FC             ; load write counter
99 62 C0    STA .outbuf,Y       ; write to output string
E6 FC       INC $FC             ; increment write counter
D0 B5       BNE .mainloop       ; back to main loop
 .outbuf:                       ; "BSS", output string is stored from here

Remarks:

  • Input validation is fully implemented (and takes quite a few bytes, otherwise it would be possible to directly output each decoded nibble without temporary storage)

  • I took the liberty to interpret "any length" as "any length my C64 system can read from a command line as a string", which is quite limited ... 69, or if you abbreviate sys with sY 70 "bits", because the whole command line is limited to 80 characters ... hope this is acceptable :)

Screenshot

Felix Palmen

Posted 2017-08-27T20:07:14.940

Reputation: 3 866

1

R, 34 bytes

function(x)as.hexmode(strtoi(x,2))

Returns NA for invalid input.

Try it online!

Giuseppe

Posted 2017-08-27T20:07:14.940

Reputation: 21 077

1

05AB1E, 7 6 bytes

CbQ*Ch

Try it online!
Error case

It's my first try ever to a Code Golf, advices welcomed!
Handles error cases \o/

The idea is to make the conversion from base 2 to base 10, and back to base 2. Compare the result with the initial input, if it's not the same, then the conversion have failed.

1012101 => 0
a => empty
-1010101 => 0
abcdef => empty
2 => 0

Explanation

CbQ*Ch
C  # convert input from base 2 to base 10
 b # ...and back to 2
  Q # 1 if the full conversion back and return equals the input, else 0
   * # multiply to get 0 if error case
    C # convert corrected input from base 2 to base 10
     h # convert it to base 16 

Cyril Gandon

Posted 2017-08-27T20:07:14.940

Reputation: 199

1You could use b instead of 2B – Emigna – 2017-09-05T13:52:20.563

1

Ruby, 27 25 bytes

->b{'%x'%Integer('0b'+b)}

Try it online!

-2 bytes thanks to histocrat.

Inputs and outputs strings.

String#to_i vows to never throw an exception, returning 0 for many invalid inputs. That would be fine, except for this property:

Extraneous characters past the end of a valid number are ignored.

Meaning that 1012101 is read up to the 2 and interpreted as 101 (or 5), which is no good. We can use the stricter Integer() instead, which throws an exception for any number that is not binary. It lets through negative numbers, so we need to invalidate those by prepending 0b to the input. 0 as input returns 0, which is within the specification.

Snack

Posted 2017-08-27T20:07:14.940

Reputation: 251

I don't think you need the ,2 unless I'm missing some corner case, since you're already specifying base 2 with the '0b'. – histocrat – 2017-11-20T22:39:23.507

@histocrat This was long enough ago that I can't really remember but I suspect you're right. Thanks! – Snack – 2017-11-21T22:31:42.890

1

Tcl, 66 bytes

proc H b {expr {[regexp ^\[01\]+$ $b]?[format %x [scan $b %b]]:0}}

Try it online!

sergiol

Posted 2017-08-27T20:07:14.940

Reputation: 3 055

There was a bug in fifth test case. Fixed now. – sergiol – 2017-12-23T11:39:55.937

0

Python 3, 52 29 26 bytes

print(hex(int(input(),2)))

benzene

Posted 2017-08-27T20:07:14.940

Reputation: 257

It's not very golfy – Zacharý – 2017-08-27T20:33:22.497

Unfortunately, since the OP changed the rules it now only differs by being a more verbose function definition. – cole – 2017-08-27T21:17:50.180

...plus (like the other one) does not exit, error or yield 0 for all invalid inputs. (Also you have not updated the TIO link from the 52 byter)

– Jonathan Allan – 2017-08-27T23:09:57.680

You might be able to change it to Python2 (and remove the parens after print), since it would error on invalid inputs due to various different reasons. – Zacharý – 2017-08-27T23:22:19.583

@Zacharý Sadly Python 2 doesn't seem to have a hex() builtin – benzene – 2017-08-27T23:27:35.357

Okay then, -__- – Zacharý – 2017-08-28T11:15:38.210

0

Rust, 58 57 bytes

Saved one byte using 8 bit int

|n:&str|format!("{:x}",u8::from_str_radix(n,2).unwrap());

Ungolfed

fn main() {
    let bin = "101";
    println!("{:x}", u8::from_str_radix(bin, 2).unwrap()); // 5
}

Try it online!

Noskcaj

Posted 2017-08-27T20:07:14.940

Reputation: 421

0

Kotlin 1.1, 92 bytes

Submission

fun r(i:String):String{return if(i.matches(Regex("[01]+")))i.toLong(2).toString(16)else "0"}

Beautified

fun r(i: String): String {
    return if (i.matches(Regex("[01]+"))) {    // If it is valid
        i.toLong(2)                            // Convert to Long
         .toString(16)                         // Return as hex
    } else {                                   // Otherwise
        "0"                                    // Return 0
    }
}

Explanation

  • The number is checked to be valid by the regex
  • Kotlin to and from string methods are used to convert the string

Unfortunately this does not run on TryItOnline, as it uses newer Kotlin features

jrtapsell

Posted 2017-08-27T20:07:14.940

Reputation: 915

0

Stacked, 24 bytes

[:\'1|0'-#'0=\unbin*hex]

Try it online!

Conor O'Brien

Posted 2017-08-27T20:07:14.940

Reputation: 36 228

0

Dyvil, 32 Bytes

s=>Int.parseInt(s,2).toHexString

Pretty much self-explanatory. Throws a NumberFormatException for invalid inputs. Output without 0x.

Clashsoft

Posted 2017-08-27T20:07:14.940

Reputation: 835

0

Javascript (ES6) 50 45 39 bytes

h=
s=>isNaN(n=+('0b'+s))?0:n.toString(16)   
<input id="i" type="text" onchange="o.innerHTML=h(i.value)"><pre id="o"></pre">

with thanks to Shaggy 6 bytes less. Or for a 26 byte version that returns 'NaN' instead of '0' on error:

s=>+('0b'+s).toString(16)

'0b' was introduced as a binary number prefix in ES6.

traktor53

Posted 2017-08-27T20:07:14.940

Reputation: 299

You should be able to save some bytes by moving the assignment of n within isNaN and then removing the parentheses from the function parameter. Also, does the 0 need to be a string? – Shaggy – 2017-08-28T07:29:47.030

@Shaggy - new ways to be sneaky, thanks. And also agree that 0 converts to '0' automatically when inspecting/printing the result. – traktor53 – 2017-08-28T09:36:19.247

0

Python 2, 27 bytes

lambda s:hex(int('0b'+s,2))

Try it online!

We invalidate inputs like 0b1010 or -1010 by prefixing 0b ourselves — because 0b0b1010 and 0b-1010 are invalid base 2 literals in Python.

Lynn

Posted 2017-08-27T20:07:14.940

Reputation: 55 648

eval('0b'+s) for a byte – Uriel – 2017-08-28T15:48:58.710

No, it’s too strong! Inputs like "0+4*5" will yield 20. – Lynn – 2017-08-28T17:28:12.917

0

Perl 6, 19 bytes ( = 18 + 1 for "-p" )

perl6 -pe '$_=:2($_).base: 16'

Nothing creative. The :2(string) construct takes the string and interprets it as a number in base 2. (This works for arbitrary bases up to base 36.) The base method takes a number and gives a string representation in the given base.

Due to -p, it loads one line from stdin at a time, expecting each to contain one number. If you feed it something that's not valid binary number, you get an error and the program ends.

Ramillies

Posted 2017-08-27T20:07:14.940

Reputation: 1 923

0

Lua, 43 40 bytes

print(("").format("%x",tonumber(...,2)))

I think it explains itself. Parses from base 2 to decimal then formats it to hex. If it is not binary input it will simply error (tested with Lua 5.2,5.3).

Lycea

Posted 2017-08-27T20:07:14.940

Reputation: 141

0

Javascript, 28 bytes

x=>eval("0b"+x).toString(16)

evals x with a 0b in front of it, turning it into a binary literal. Binary literals error out on non binary values of x. .toString(16) turns x into a hexdecimal.

SuperStormer

Posted 2017-08-27T20:07:14.940

Reputation: 927

0

Perl 5, 30 + 1 (-n) = 31 bytes

printf"%x",!y/01//c&&oct"0b$_"

Try it online!

Xcali

Posted 2017-08-27T20:07:14.940

Reputation: 7 671

0

REXX, 15 bytes

say b2x(arg(1))

idrougge

Posted 2017-08-27T20:07:14.940

Reputation: 641

0

Julia, 24 bytes

f(x)=hex(parse(Int,x,2))

Try it online!

EricShermanCS

Posted 2017-08-27T20:07:14.940

Reputation: 121

0

Common Lisp, 48 bytes

(format t"~X"(parse-integer(read-line):radix 2))

Try it online!

Renzo

Posted 2017-08-27T20:07:14.940

Reputation: 2 260

0

Bash, 19 bytes

printf %x $((2#$1))

Try it online!

ბიმო

Posted 2017-08-27T20:07:14.940

Reputation: 15 345

0

><>, 84 82 Bytes

Improved somewhat. Probably still improvable.

l&1>:}*{$}2\~-?\02.
~~&\?&:-1&*/1l+<
>:f1+%:}\
\?:,+1f-/.47r~
)a:;!?ln/?
.47o+*b5/

Old version:

1l&>:}*{$}2\
~~&\?&:-1&*/l +<
>:f1+%:}-f1\1-?/
\?      :,+/r~
n/?)a:;!?l <
5/.4co+*b

I'll work on improving it later, see if I can get rid of that big chunk of whitespace.

How it works:

(This is for the old version, new version works the same but with loops in different positions)

Implicit input, assumed to be a series of bits such as '1,1,1,0,0', with the ones place on the right, as normal.

l&1

Store the length in the registry; push 1 to the stack. The 1 will record which place we are on in the binary number.

   >:}*{$}2\
   \?&:-1&*/

Replace each bit with the value it represents. For example, 1,1,1,0 goes to 8,4,2,0.

~~&

Delete the counter and position-measurer.

           /l +<
           \1-?/

Sum the stack. Results in the number that was represented in binary.

>:f1+%:}-f1\
\?      :,+/

Convert this to hexadecimal, which unfortunately reverses it and leaves a trailing 0. For example, 28 becomes 12, 1, 0.

           /r~

Remove the trailing zero and un-reverse it.

n/?)a:;!?l <
5/.4co+*b

This is all for printing. If the value is <10, just print it normally. Otherwise, add 55 and print the ascii character of this number.

Bolce Bussiere

Posted 2017-08-27T20:07:14.940

Reputation: 970

0

><>, 50 bytes

{:?v~
!v0>}l4%?
 r
4<]nv?)9:+++*2}*4}*8[
+"W"<.33o

Try It Online

Complies with the question by erroring on invalid input, but as it always ends with an error anyway, this is a bit tongue in cheek.

How It Works

{:?v~ Pops leading 0s
...

...
!v0>}l4%? Adds leading 0s until the length of the binary is divisible by 4
 r        And reverses the input
...

...                   Repeatedly take the last 4 digits of the binary
4<]nv?)9:+++*2}*4}*8[ Calculate the value of those digits and print the hexadecimal value
+"W"<.33o             If the value is above 9, print the appropriate letter

Jo King

Posted 2017-08-27T20:07:14.940

Reputation: 38 234