Hi again. Building, kind of, from my post the other day (I am moving in some form of logic here) — I am still fiddling with binary and bitwise operations. Here, I am trying to implement, or at least mimic, the JavaScript >> operator — signed/sign-propagating right bitwise shift. Perl's >> seems to be unsigned/zero-filling, behaving the same as the JavaScript >>>.

What I have below seems to give me what I want. It spits out the same results as the equivalent JavaScript — though my working knowledge of JavaScript is more that of a fiddler than a serious programmer. The below presumes (as I think the JavaScript operators do?) that I'm working with signed 32-bit integers; and for this instance I think that is probably fine. (What I'm trying to do with all this is implement Paj's JavaScript MD5 library in Perl, so my Perl script will encrypt my password appropriately and login to a website correctly.)

So, my questions:

  1. Am I reinventing the wheel here? Are there Perl modules already that do what Paj's does? (If there are, I will not complain, because at least I am learning a lot.)
  2. Is there a way to change the behavior of Perl's bitwise operators, to do what I need them to do? I seem to need to use both the JavaScript >> (signed/sign-propagating) and >>> (unsigned/zero-filling) in the same scope.
  3. Or, is there an (easy) way to define an >>> operator in Perl (as of v5.14) that behaves as I need it to? (I know that I could overload the >> operator, but that without the other wouldn't help me.)
  4. Would what I have below work in every case?
  5. Is there a more elegant way to do what I'm doing below?

#!/usr/bin/perl use strict; use warnings 'all'; use Config; my $longsize = $Config{longsize}; my $firstbit = ($longsize * 8) - 1; sub rshift { # Should be signed/sign-propagating right shift my ($x, $y) = @_; foreach (my $i = 0; $i < $y; $i++) { my $lbit = (($x & (1 << $firstbit)) != 0); $x = ($x >> 1) | ((1 << $firstbit) * $lbit); } return unpack("l>", pack("l>", $x)); } sub bin_test_print { printf("%032b = %d\n", $_[0], $_[0]); } my $x = 9; bin_test_print($x); $x = rshift($x, 2); bin_test_print($x); print "\n\n"; $x = -9; bin_test_print($x); $x = rshift($x, 2); bin_test_print($x); print "\n\n"; $x = 12345; bin_test_print($x); $x = rshift($x, 2); bin_test_print($x); print "\n\n"; $x = -12345; bin_test_print($x); $x = rshift($x, 2); bin_test_print($x);

UPDATE: Thanks, everybody, for all your help. Through repeatedly beating my head against this bitwise problem, and spending a whole lot of time dissecting code and playing with encryption routines -- I have figured out that, yes, I was, in fact, re-inventing the wheel. Not only did the Digest::MD5 package take care of what Paj's MD5 JavaScript module does, but I realized that the website I'm working with doesn't even use MD5 encryption for its login -- just simple Base64 encoding. The issue that was throwing me was that there were two passwords being sent with the form, an encrypted one (in fact just Base64) and a seemingly doubly-encrypted one -- which turned out, after painstakingly working through the bitwise math of Paj's whole module, figuring out exactly what he was doing to the bits at every step, merely to be the same thing -- the Base64 encoding of the password, only expanded to UTF16. D'oh! And once I realized this, I re-created it in Perl in five minutes with just the little bit of code below. But at least, now, and finally, I can say that I understand bitwise operations and binary representation of integers. Many thanks.

use strict; use warnings 'all'; use MIME::Base64; sub b64_password { return MIME::Base64::encode($_[0]); } sub b64_utf16_password { my @ascii = unpack("C*", $_[0]); my $utf16 = pack("v*", @ascii); my $base64_utf16 = MIME::Base64::encode($utf16); return $base64_utf16; }


In reply to Implementing a signed/sign-propagating right bitwise shift by LonelyPilgrim

Title:
Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post, it's "PerlMonks-approved HTML":



  • Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
  • Titles consisting of a single word are discouraged, and in most cases are disallowed outright.
  • Read Where should I post X? if you're not absolutely sure you're posting in the right place.
  • Please read these before you post! —
  • Posts may use any of the Perl Monks Approved HTML tags:
    a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, details, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, summary, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
  • You may need to use entities for some characters, as follows. (Exception: Within code tags, you can put the characters literally.)
            For:     Use:
    & &amp;
    < &lt;
    > &gt;
    [ &#91;
    ] &#93;
  • Link using PerlMonks shortcuts! What shortcuts can I use for linking?
  • See Writeup Formatting Tips and other pages linked from there for more info.