کار با داده های باینری – میهن مهر

working-with-binary-data

آیا bash می‌تواند داده‌های باینری را اداره کند؟

به طور اساسی پاسخ خیر است….

در حالیکه bash مشکلاتی به زیادی پوسته‌های قدیمی‌تر با آنها ندارد، باز هم نمی‌تواند داده‌های باینری اختیاری را پردازش نماید، و به طور اخص، متغیرهای پوسته ‎ ۱۰۰%‎ باینری خالص نیستند، بنابراین نمی‌توانید فایلهای باینری را در آنها ذخیره کنید.

شما می‌توانید داده‌های اسکی کُدگذاری شده یونیکس به یونیکس(uuencoded) را به این طریق در متغییر قرار دهید:

    var=$(uuencode /bin/ls ls)
    cd /somewhere/else
    uudecode <<<"$var"  # نقل‌قولها را فراموش نکنید
  • توجه: تفاوت سترگی میان uuencode یا uudecode گنو و یونیکس وجود دارد. با uudecode یونیکس، شما نمی‌توانید فایل خروجی تعیین کنید، همواره از نام فایل کدگذاری شده در داده اسکی استفاده می‌کند. من مثال قبلی را اصلاح کرده‌ام به طوری که در سیستم‌های یونیکس کار می‌کند. اگر شما تغییرات بیشتری ایجاد می‌کنید، لطفاً رویه‌گرایی گنو (GNUisms) را به کار نبرید. متشکرم.–GreyCat

یک نمونه که چنین موردی ممکن است گاهی در آن سودمند باشد، ذخیره کردن نقشه‌بیتی‌های کوچک موقتی، در هنگام کار کردن با netpbm است… در اینجا من به یک pnmnoraw زیرنویس ۱ اضافی در لوله متوسل شدم که باعث ایجاد فایلهای اسکی بزرگتر می‌شود و bash با ذخیره آنها مشکلی ندارد.

اگر احساس ماجراجویی دارید، این تجربه را ملاحظه نمایید:

# bindec.bash, سعی می‌کند داده‌های باینری را به اسکی دسیمال رمزگشایی کند‎
IFS=
while read -n1 x ;do
  case "$x" in
     '') echo empty ;;
     # ‏۲۵۶ سطر تولید شده توسط سطر فرمان زیر را در اینجا درج کنید ‎
     # for x in $(seq 0 255) ;do echo "     $'\\$(printf %o $x)') echo $x;;" ;done
  esac
done

و سپس داده باینری را به آن لوله‌کشی کنید، شاید اینطور :

    for x in $(seq 0 255) ;do echo -ne "\\$(printf %o $x)" ;done | bash bindec.bash | nl | less

این کد ایجاب می‌کند که کاراکتر ۰ به طور کلی از قلم انداخته شود، زیرا ما نمی‌توانیم آنرا با تولید کننده ورودی ایجاد کنیم، به راحتی برای خراب کردن اکثر فایلهای باینری که می‌خواهیم پردازش کنیم، کفایت می‌کند.

  • بلی، Bash به زبان C نوشته شده، و از معناشناسی این زبان برای مدیریت رشته‌ها — شامل بایت‌های NUL به عنوان حدفاصل رشته‌ها — در متغیرهایش استفاده می‌کند. شما نمی‌توانید به طور معقولی NUL را در متغیرهای Bash ذخیره نمایید. در حقیقت هرگز هم قرار نبوده به این صورت به کار برود. – GreyCat

توجه نمایید که این مطلب اشاره به نگهداری آنها در متغیرها دارد… انتقال داده‌ها بین برنامه‌ها با استفاده از لوله‌ها همیشه باینری بدون عیب است. فایلهای موقتی نیز به شرطی که موقع ایجاد آنها اقدامات احتیاطی متناسب انجام بشود، بی‌خطر هستند.

برای cat کردن فایل باینری تنها با دستورات داخلی bash موقعی که برنامه خارجی در دسترس نباشد(یکبار وقتی نام فایل‎ /lib/libgcc_s.so.1‎ تغییر کرده بود، استفاده از این ترفند کارم را راه انداخت):

# باینری مطمئن bash فقط با دستورات داخلی cat شبیه‌سازی 
IFS=
while read -d '' -r -n1 x ; do
    case "$x" in
        '') printf "\x00";;
        *) printf "%s" "$x";;
    esac
done
  • من ترجیح خواهم داد از cat استفاده کنم. همچنین، آن ‎-n1‎ واقعاً لازم بود؟ -GreyCat
    • بدون ‎-n1‎ شما باید برای کار کردن با داده‌های بعد از آخرین ‎ \۰‎ خیلی با احتیاط باشید، موردی مانند این ‎[[ $x ]] && printf "%s" "%x"‎ بعد از حلقه. من این را بررسی نکرده‌ام که بدانم آیا کار می‌کند یا اینکه کافی هست. همچنین من نمی‌دانم اگر شما یک فایل بزرگ بدون هیچ ‎ \۰‎ را بخوانید چه اتفاقی می‌افتد –pgas

هر رقم در یک عدد باینری یک بیت (bit) نامیده می شود. بیت کوچکترین واحد اطلاعاتی در کامپیوتر است.

بیت ها به گروه های بزرگتری سازماندهی می شوند؛ در کامپیوترهای امروزی هر هشت بیت یک بایت (Byte) درنظر گرفته می شود که کوچکترین مکان آدرس پذیر حافظه است (که می تواند متفاوت از مقدار حافظه واکشی شده درهربار مراجعه باشد). یک بایت می تواند حاوی یک دستورالعمل ماشین، یک کاراکتر، یا یک عدد باشد.

یک نیبل (nibble) نیمه یک بایت یا چهار بیت است.

نوع بزرگتر ذخیره سازی یک کلمه (word) است که روی پردازنده های اینتل ۲ بایت (۱۶ بیت) است. یک کلمه طول پیش فرض داده است که توسط طراح پردازنده انتخاب شده است و منعکس کننده برخی نکات سخت افزاری نظیر گذرگاه های درونی و بیرونی است. کامیپوترهای شخصی اولیه با پردازنده های اینتل دارای عملوندهای ۱۶ بیتی بودند به همین دلیل کلمه به صورت ۱۶ بیتی تعریف شد. در پردازنده های دیگر طول کلمه الزاما ۲ بایت نیست.

working-with-binary-data

یک کلمه مضاعف (doubleword) چهار بایت یا ۳۲ بیت طول دارد و یک کلمه چهارگانه (quadword) دارای هشت بایت یا ۶۴ بیت است.

endian

یک نکته مهم دیگر بعد از تعداد بیت ها ترتیب قرار گیری بایت های داده در حافظه است که باید موردتوجه برنامه نویس اسمبلی باشد. درحینی که پردازنده به طور نامحسوس endian را استفاده می کند، برای دسترسی به داده های چندبایتی حافظه و کارکردن با هر بایت بطور جداگانه، دانستن endian حیاتی است. endian ترتیب قرار گیری بایت ها در حافظه را برای داده های چندبایتی معین می کند. فرمت های زیر برای ذخیره یک مقدار چندبایتی وجود دارد:

۱٫ Big-endian
• داده ها را به ترتیب طبیعی خودشان ذخیره می کند. بایت با ارزش در کمترین آدرس قرار می گیرد. اکثر پردازنده های RISC و Motorola 68300 از این دسته هستند.
۲٫ Little-endian
• بایت با ارزش کمتر در آدرس های پائین تر حافظه ذخیره می شود. پردازنده های Intel x86 و Pentium از این نمونه هستند.
۳٫ Bi-endian
• پردازنده هائی مانند Motorola/IBM PowerPC می تواند در مد big-endian یا little-endian تحت کنترل نرم افزار کار کند.

مثال. داده چهار بایتی هگزAABBCCDD را درنظر بگیرید. نحوه تخصیص حافظه به این داده در دو فرمت endian به صورت زیر نشان داده شده است. مشاهده می شود که این دو فرمت عکس یکدیگر هستند.

working-with-binary-data

روش های نمایش داده ها

اطلاعات معمولا به دو صورت استفاده می شوند: داده عددی ( صحیح و ممیرشناور) و داده حرفی. نحوه نگهداری اطلاعات در حافظه را نمایش داده می گویند. روش های نگهداری داده ها بسته به نوع آنها متفاوت است.

working-with-binary-data

منبع : http://mehrmihan.ir/working-with-binary-data/


ادامه مطلب

پاسخ دهید

نشانی ایمیل شما منتشر نخواهد شد.

Time limit is exhausted. Please reload CAPTCHA.