Monday, May 25, 2015

Convert index to letter excel like

Follow extension methods allow to convert a number to a string ( mostly used to refer a spreadsheet column name ) and back the string to column index ( first column index = 0 ).


#region Lib0.Spreadsheet, Copyright(C) 2015 Lorenzo Delana, License under Ms-PL
/*
 * This source is subject to the Microsoft Public License (Ms-PL).
 * Please see http://www.microsoft.com/en-us/openness/licenses.aspx for details.
 * 
 * Author : Lorenzo Delana <user@searchathing.com>
 * 
 * Contributors :
*/
#endregion

using System.Text;

namespace Lib0.Spreadsheet
{

    public static class Ext
    {

        static readonly string Alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";

        /// <summary>
        /// Convert spreadsheet column string to index (first column index = 0).        
        /// Pre: value must non empty uppercase letters.
        /// </summary>                
        public static int LetterToIndex(this string value)
        {
            var sb = new StringBuilder();

            return LetterToIndex(value, 0, sb);
        }

        /// <summary>
        /// LetterToIndex (recursive body).
        /// </summary>        
        static int LetterToIndex(this string value, int curIdx, StringBuilder sb)
        {
            var res = 0;

            int pow = value.Length - curIdx - 1;
            int charpos = value[curIdx] - Alphabet[0];

            if (pow > 0)
            {
                var x = 1; do { x *= 26; --pow; } while (pow != 0);
                res += x * (charpos + 1);

                res += LetterToIndex(value, curIdx + 1, sb);
            }
            else
                res += charpos;

            return res;
        }

        /// <summary>
        /// Convert index to spreadsheet column (first column index = 0).
        /// </summary>        
        public static string IndexToLetter(this int index)
        {
            if (index < 0) return string.Empty;

            var sb = new StringBuilder();

            IndexToLetter(index, sb);

            return sb.ToString();
        }

        /// <summary>
        /// IndexToLetter (recursive body).
        /// </summary>        
        public static void IndexToLetter(this int index, StringBuilder sb)
        {
            do
            {
                var x = index / 26;
                var r = index % 26;

                if (x > 0)
                    IndexToLetter(x - 1, sb);
                else
                    sb.Append(Alphabet[r]);

                if (x == 0) break;

                index -= 26 * x;
            }
            while (index >= 0);
        }

    }

}


Timing considerations

Pow using double

test total time : 00:00:06.9890933


Pow using integer

test total time : 00:00:04.7791627

Considerations about the Math.Pow


  • test timing difference total : about 2 seconds
  • timing difference from the inclusive samples 2118 (using Math.Pow) vs 205 (using custom integer pow)

Why int Math.Pow(int, int) extension method cannot exists

I think, but not sure, that the reason why Math.Pow not have an overloaded method is cause :
  • power of number using integers can easily run overflow
  • introduce such method now will results in an inconsistent behavior of the current code cause the current method upcast integer arguments to double, so that I could have :
    • Math.Pow(20, 100) returns about 1.25e130
    • Math.Pow(20, 100) return 0
A solution to avoid conflict could be to add an Math.IPow(int,int) using different name or create your own extension.


Creative Commons License
Convert index to letter excel like by Lorenzo Delana is licensed under a Creative Commons Attribution 4.0 International License.

Sunday, May 24, 2015

Banana-pi encrypted sata disk bootstrap

Follow some annotation how to bootstrap banana-pi with encrypted sata disk.

Update: an extended guide is available here including notes on how to configure firewall, email server, etc.

Prerequisites

  • banana-pi
  • power supply usb micro 5V 2A
  • banana-pi dedicated sata cable
  • hdd 2.5" sata
  • sd card (at least 2gb)
  • hdmi cable (for initial setup)
  • usb keyboard (for decryption password at bootstrap)

Preamble

Pro

  • entire operating system ( except boot that runs from sd card ) is encrypted

Cons

  • sata write speed test shows a slow down from ~40mb/s to ~15mb/s
  • dual threaded kernel worker at 90% during write operation ( this is normal then testing a 500mb continuous file writing )

Cautions

  • backup all your data present in the sata disk before to proceed, encrypting whole disk with this method imply partitioning and formatting

Overview

SD card partition layout

  • /dev/mmcblk0p1 (boot partition ~20mb)
  • /dev/mmcblk0p2 (sd card root partition ~1.8gb)

SATA disk partition layout

  • /dev/sda1 (encrypted root partition)

Bootstrap path

  • /dev/mmcblk0p1 ( uImage [linux kernel] then uInitrd [initial ramdisk] )
  • /dev/sda1 (root filesystem)

Steps

Install operating system in the sd card

Install needed packages

  • install cryptsetup using apt-get install cryptsetup
  • install initial ramdisk util with apt-get install initramfs-tools
  • install Uimage tool apt-get install uboot-mkimage

Install operating system in the sata disk

  • boot from sd card

Create partition

  • fdisk /dev/sda and create 1 primary partition for entire disk

Encrypt partition and create filesystem

Setup crypt table and create initial ramdisk

  • edit /etc/crypttab inserting follow cryptroot  /dev/sda1  none  luks spacing fields using the tab key
  • edit /etc/fstab inserting follow /dev/mapper/cryptroot / ext4 defaults 1 2

Mount encrypted partition and copy operating system

  • mount the unencrypted filesystem using mkdir /x ; mount /dev/mapper/cryptroot /x
  • copy the operating system from the sd card to the sata disk using rsync -arx --exclude="/x*" / /x

Create initial ramdisk and set uInitrd image

  • mount the sd card p0 partition with mkdir /b ; mount /dev/mmcblk0p1 /b
  • create initial ramdisk with mkinitramfs -o /b/initrd
  • create uInitrd image with cd /b ; mkimage -A arm -O linux -T ramdisk -C gzip -a 0 -e 0 -d initrd uInitrd

Adjusting kernel parameters

  • edit /b/uEnv.txt as follow
bootargs=console=ttyS0,115200 console=tty0 sunxi_g2d_mem_reserve=0 sunxi_ve_mem_reserve=0 disp.screen0_output_mode=EDID:1280x720p50 hdmi.audio=EDID:0 console=tty1 cryptdevice=/dev/sda1:cryptroot root=/dev/mapper/cryptroot rootfstype=ext4 elevator=deadline raid=noautodetect rootwait
aload_script=fatload mmc 0 0x43000000 script.bin;
aload_kernel=fatload mmc 0 0x48000000 uImage; fatload mmc 0 0x49000000 uInitrd; bootm 0x48000000 0x49000000;
uenvcmd=run aload_script aload_kernel

Reboot

  • umount /b ; sync ; reboot

Notes

  • the initial ramdisk is a gzipped archive ( you can see the content by follow mkdir /tmp/initrd ; cd /tmp/initrd ; gunzip -c /b/initrd| cpio -i ; ls ). This special post-kernel image contains some routines for bootstrap that will starts withing the init script ( see /tmp/initrd/init ).

Bananian 15.08 ( Jessie )

Replace above sections with follow if using 15.08 bananian.

Install needed packages

  • apt-get install cryptsetup initramfs-tools u-boot-tools

Create initial ramdisk and set uInitrd image

  • mount the sd card p0 partition with mkdir /b ; mount /dev/mmcblk0p1 /b
  • create initial ramdisk with mkinitramfs -o /b/initrd
  • create uInitrd image with cd /b ; mkimage -A arm -T ramdisk -C none -n uInitrd -d initrd uInitrd

Adjusting kernel parameters

  • replace /b/boot.cmd contents with follow
setenv bootargs console=ttyS0,115200 console=tty0 console=tty1 sunxi_g2d_mem_reserve=0 sunxi_ve_mem_reserve=0 hdmi.audio=EDID:0 disp.screen0_output_mode=EDID:1680x1050p60 cryptdevice=/dev/sda1:cryptroot root=/dev/mapper/cryptroot rootfstype=ext4 elevator=deadline rootwait
setenv bootm_boot_mode sec
fatload mmc 0 0x43000000 script.bin
fatload mmc 0 0x41000000 uImage
fatload mmc 0 0x50000000 uInitrd
bootm 0x41000000 0x50000000
  • compile boot.cmd to boot.scr with mkimage -C none -A arm -T script -d boot.cmd boot.scr



Creative Commons License
Banana-pi encrypted sata disk bootstrap by Lorenzo Delana is licensed under a Creative Commons Attribution 4.0 International License.