php image steganography nearly same start - php

i am working on a php-script which encodes given text and hides that in an Image using LSB. But the encoded text is a Byte Array (text encrypted using mcrypt with rijndael-256 and then unpacked with unpack("C*", $encryptedText);) i have tp add the array-size at the beginning of the Array. if i would not do this, reading the Bytes from the Image again would be terrible later on, because the script would not know where to stop reading. I added size Information at the beginning of the Array using These lines of code:
$size = count($byteArray);
array_unshift($byteArray, $size >> 24, ($size & 0xff0000) >> 16, ($size & 0xff00) >> 8, $size & 0xff);
so the size is added in integer Format (4bytes), but now every Image created would have the characteristics that the first hidden Bytes start mostly with Zeros, besause $size is mostly in the range of 60000 or lower. is there any way i can encode size or Change other parts of the program so that it works and the beginning of the bytearry is not nearly the same every time?

Instead of always having the first 4 bytes encoding how long your message is, you can use the last two bits from the first byte to encode how many bytes you need to read for $size. Say, 00 = 1, 01 = 2, 10 = 3 and 11 = 4. For example, if $size is small enough to be expressed with just two bytes, the first few bytes will read as follow:
First byte: xxxxxx01
Second and third bytes: $size
Fourth byte and onward: ByteArray...
You can spice things up further by using a randomised embedding method. You can use a pseudorandom number generator, or chaotic maps, such as the Logistic Map, or Tent Map. The seed or initial condition parameters will be required by the receipt to decipher in what order to read the bytes to extract the message. For example, consider 5 bytes to embed data and 5 numbers generated between 0 and 1.
(0.2843, 0.5643, 0.0904, 0.4308, 0.9866)
Sorting the numbers in ascending order gives you the following order, which you can use to embed your secret:
(3, 1, 4, 2, 5)

Related

Is it possible to read a certain number of characters after a certain number of digits from the start of the file

I'm setting up a web app, where users can choose the starting point and the number of characters to read from a text file containing 1 billion digits of pi.
I have looked, but I can't find any similar problems. Because I don't know what the starting digit is, I can't use other solutions.
Here is the function written in Python:
def pi(left : int, right : int):
f.seek(left+1)
return f.read(right)
For example, entering 700 as the starting point and 9 as the number of characters should return "Pi(700,9): 542019956".
Use fseek to move the file pointer to the position you need, and fread to read the amount of characters you need - just like your Python sample code.
Actually, this capability is built in to file_get_contents.
$substr = file_get_contents('pi_file.txt', false, null, 700, 9);
A handy feature of that function that I learned about just now after using it for the past 7 years.

Creating a code128 barcode in PHP, using a font instead of rendering it as an image

I need to be able to convert any string into a code128 barcode that can be printed on a PDF.
My idea was to embed a code128 font into the PDF and simply use that font to render the string that I need to show as a barcode, letter for letter.
However, I found out that I also need to calculate a checksum and include the start and stop characters.
Is this not possible using PHP? I have not found any solution anywhere. The only solutions that I could find are for directly rendering the barcode as an image, which does not help in my current situation, since I need to use a font to create the barcode in the PDF.
If you restrict your efforts to 128B, you have access to upper and lower case characters, numbers and most punctuation. It also saves you from having to write code to shift in and out of A and C symbologies. This makes the code to calculate the checksum really trivial.
Code 128B start character has a value of 104. The stop character for all Code 128 variations has a value of 106, but that value does not figure into the chksum calculation. Let's pick the string "Hello" for a real life exercise. You'll want to make sure you have access to the Code 128 table. All the values I will be discussing are out of that table and not ASCII or UTF-8.
The checksum is calculated by adding the multiple of a character’s value by its position in the barcode with the exception of the start code.
While the start code’s position is ‘1’, so is the position of the first character following the start code. So the start code and the first byte of data (‘H’) are both multiplied by the number 1 ((104 × 1) + (40 × 1) = 144).
The following 4 bytes get an incrementally higher multiplier ((69 x 2) + (76 × 3) + (76 × 4) + (79 × 5) = 1065). Summing it all up together (144 + 1065) we get 1209.
You should be able to use the modulus operator (1209 % 103) in PHP to get 76 for the checksum character for the Code 128B string “Hello” (the 103 is a constant, trust me on that). So the final array of codes to map "Hello" into a Code 128 barcode is:
[104 40 69 76 76 79 76 106].
You'll need lookup tables to convert the string character values to Code 128B character values to whatever your barcode font is expecting. But all you need is a loop, an array index, an accumulator for the sum of the factors and a modulus operator against the constant value of 103.
The easisest way to generate a barcode in PHP for PDF is to use a dedicated software library.
AFAIK, the most complete one is currently the tc-lib-barcode (https://github.com/tecnickcom/tc-lib-barcode) that allows you to generate both linear and bidimensional barcodes. The included example should give you a quick start.
The source code is fully PSR-2 compliant and can be easily added to your PHP projects using Composer.
The original code has been ported and refactored from TCPDF and already used in billions of documents.

Byte size of string in PHP [duplicate]

This question already has answers here:
Measure string size in Bytes in php
(5 answers)
Closed 8 years ago.
I have an encrypted image and before saving it I would like to know how much space it takes up. I can get the number of characters via strlen($img) or via mb_strlen($img) but I would like to get a number like 16KiB (or KB).
I then save the string into a MySQL database in blob format, where I can see the size of it using PhpMyAdmin.
EDIT
If I use strlen to get the byte size of the string (which I want) I get a different value from the byte size displayed in my MySQL database (where the string is not saved as a char but as a blog, meaning binary). How can this be? And how can I find out how large the binary size will be when I save the string in the database.
I save the string simply with the MySQL command
INSERT INTO table (content, bla) VALUES ($string, bla);
(not fully correct but for example purpose – this works when correct)
Now when I look inside my database it displays me a size e.g 315 KB but when I take $string and do strlen on it, it returns something like 240000 (Not the same in bits as in KB)
I will investigate my self...
This does essentially the same thing as Dany's answer, but a little more compact.
function human_filesize($bytes, $decimals = 2) {
$size = array('B','kB','MB','GB','TB','PB','EB','ZB','YB');
$factor = floor((strlen($bytes) - 1) / 3);
return sprintf("%.{$decimals}f", $bytes / pow(1024, $factor)) . #$size[$factor];
}
echo human_filesize(filesize($filename));
Source: http://jeffreysambells.com/2012/10/25/human-readable-filesize-php

Convert HEX to ASCII, data from GPS tracker

I have just bought a GPS Tracker, it can send SMS to cellphone just fine. It also supports reporting to a server via GPRS.
I have setup the device to contact my own server on port 8123, it's a FreeBSD server and i have checked that i recieve packets on that port.
I successfully have setup a listener server written in PHP, and i can receive data from the device. But how do i convert the partial HEX data to something usefull (ASCII)?
Example data string:
$$^#T^#E Y'^WÿU210104.000,A,5534.4079,N,01146.2510,E,0.00,,170411,,*10|1.0|72|0000á
Unfortunately i don't know how i can copy-paste the HEX parts
Now how do i get the ID part out? I have tried echo hexdec(mb_substr($data, 4, 7));
The data is following this protocol
From the document:
Command format of GPRS packets are as follows:
From server to tracker:
##\r\n
From tracker to server:
$$\r\n
Note:
Do NOT input ‘’ when writing a command.
All multi-byte data complies with the following sequence: High byte prior to low byte.
The size of a GPRS packet (including data) is about 100 bytes
Item Specification
## 2 bytes. It means the header of packet from server to tracker.
It is in ASCII code (Hex code: 0x40)
$$ 2 bytes. It is the header of packet from tracker to server.
It is in ASCII code (Hex code: 0x24)
L 2 bytes. It means the length of the whole packet including
the header and ending character and it is in hex code
ID 7 bytes, ID must be digit and not over 14 digits, the unused byte
will be stuffed by ‘f’ or ‘0xff’. It is in the format of hex code.
For example, if ID is 13612345678, then it will be shown as
follows: 0x13, 0x61, 0x23, 0x45, 0x67, 0x8f, 0xff.
If all 7 bytes are 0xff, it is a broadcasting command. ID is in hex code
command 2 bytes. The command code is in hex code. Please refer to the
command list below.
data Min 0 byte and max 100 bytes. See Annex 1 for description of ‘data’.
checksum 2 bytes. It indicates CRC-CCITT (default is 0xffff) checksum of
all data (not including CRC itself and the ending character).
It is in hex code.
For example: 24 24 00 11 13 61 23 45 67 8f ff 50 00 05 d8 0d 0a
0x05d8 = CRC-CCITT (24 24 00 11 13 61 23 45 67 8f ff 50 00)
\r\n 2 bytes. It is the ending character and in hex code
(0x0d,0x0a in hex code)
Update
With the answer from Anomie, i was able to piece this together
$arr = unpack('H4length/H14id/H4cmd/H4crc/H4end', mb_substr($data, 2, 11) . mb_substr($data, -4));
var_dump($arr);
This will out put something like
array(5) {
["length"]=>
string(4) "0054"
["id"]=>
string(14) "004512345678ff"
["cmd"]=>
string(4) "9955"
["crc"]=>
string(4) "c97e"
["end"]=>
string(4) "0d0a"
}
It sounds like you are needing to convert binary data to integers or strings. The most straightforward way is to use unpack.
For example, to extract the length you already know you can use
$length_bin = substr($string, 2, 2);
To convert it to an integer, you can use something like
$length = unpack('v', $length_bin); $length = $length[1];
The 'v' code will work for the length and the checksum; if you have a number stored as 4 bytes use 'V', and for the ID you can use 'H*' to get it as a string of hex digits. Other codes are listed in the documentation.
A somewhat less straightforward way is to do the bit manipulation manually, after using unpack with C* to get an array of all the byte values. For example,
$bytes = unpack('C*', $length_bin);
$length = ($bytes[0] << 8) | $bytes[1];
You need to know the format of the messages you are going to receive from the device. You can get this info from the manufacturer. Then, depending on that, you have to create a proper listener in the server side.
I've been working with several devices like that and normally you have to create a process in the server listening to the port with a Socket (or similar). You may have an authentication process also to differentiate between devices (you can have more than one). After that, you simply get the data from the device, you parse it and you store it. Depending on the device you can also send requests or configurations.
Hope this helps
*Edit 26 April:* I have changed the question a bit, thus this seems out of place. Initial question was more on how to read the data from TCP.
I found some great articles on writing a TCP/socket server in PHP (/me slaps PHP around a bit with a large trout)
http://devzone.zend.com/article/1086
http://kevin.vanzonneveld.net/techblog/article/create_daemons_in_php/
Can't wait to get this going :)

calculate flv video file length ? using pure php

What is the best way to calculate the length of flv file using php with out external dependencies like ffmpege because client site run on shared hosting,
itry http://code.google.com/p/flv4php/, but it extract metadata and not all video contain meta data ?
There's a not too complicated way to do that.
FLV files have a specific data structure which allow them to be parsed in reverse order, assuming the file is well-formed.
Just fopen the file and seek 4 bytes before the end of the file.
You will get a big endian 32 bit value that represents the size of the tag just before these bytes (FLV files are made of tags). You can use the unpack function with the 'N' format specification.
Then, you can seek back to the number of bytes that you just found, leading you to the start of the last tag in the file.
The tag contains the following fields:
one byte signaling the type of the tag
a big endian 24 bit integer representing the body length for this tag (should be the value you found before, minus 11... if not, then something is wrong)
a big endian 24 bit integer representing the tag's timestamp in the file, in milliseconds, plus a 8 bit integer extending the timestamp to 32 bits.
So all you have to do is then skip the first 32 bits, and unpack('N', ...) the timestamp value you read.
As FLV tag duration is usually very short, it should give a quite accurate duration for the file.
Here is some sample code:
$flv = fopen("flvfile.flv", "rb");
fseek($flv, -4, SEEK_END);
$arr = unpack('N', fread($flv, 4));
$last_tag_offset = $arr[1];
fseek($flv, -($last_tag_offset + 4), SEEK_END);
fseek($flv, 4, SEEK_CUR);
$t0 = fread($flv, 3);
$t1 = fread($flv, 1);
$arr = unpack('N', $t1 . $t0);
$milliseconds_duration = $arr[1];
The two last fseek can be factorized, but I left them both for clarity.
Edit: Fixed the code after some testing
The calculation to get the duration of a movie is roughly this:
size of file in bytes / (bitrate in kilobits per second / 8)

Categories