Search code examples
awkopenwrtbusybox

Busybox awk: How to treat each character in String as integer to perform bitwise operations?


I wanna change SSID wifi network name dynamically in OpenWRT via script which grab information from internet.

Because the information grabbed from internet may contains multiple-bytes characters, so it's can be easily truncated to invalid UTF-8 bytes sequence, so I want to use awk (busybox) to fix it. However, when I try to use bitwise function and on a String and integer, the result always return 0.

awk 'BEGIN{v="a"; print and(v,0xC0)}'

How to treat character in String as integer in awk like we can do in C/C++? char p[]="abc"; printf ("%d",*(p+1) & 0xC0);


Solution

  • You can make your own ord function like this - heavily borrowed from GNU Awk User's Guide - here

    #!/bin/bash
    
    awk '
    BEGIN    {  _ord_init() 
                printf("ord(a) = %d\n", ord("a"))
             }
    
    function _ord_init(    low, high, i, t)
    {
        low = sprintf("%c", 7) # BEL is ascii 7
        if (low == "\a") {    # regular ascii
            low = 0
            high = 127
        } else if (sprintf("%c", 128 + 7) == "\a") {
            # ascii, mark parity
            low = 128
            high = 255
        } else {        # ebcdic(!)
            low = 0
            high = 255
        }
    
        for (i = low; i <= high; i++) {
            t = sprintf("%c", i)
            _ord_[t] = i
        }
    }
    
    function ord(str,c)
    {
        # only first character is of interest
        c = substr(str, 1, 1)
        return _ord_[c]
    }'
    

    Output

    ord(a) = 97