I have this mcrypt_encrypt call, for a given $key, $message and $iv:
$string = mcrypt_encrypt(MCRYPT_3DES, $key, $message, MCRYPT_MODE_CBC, $iv);
I'd like to change the mcrypt_encrypt call to an openssl_encrypt one, to future-proof this.
By having $mode = 'des-ede3-cbc' or $mode = '3DES'; and $options = true I get the more similar response, but not identical. Is there other way to call it to get a perfect match?
I am getting this (base64_encoded) for a lorem-ipsum $message+$key combinations, so I am starting to believe one function or the other are padding somewhat the message before encrypting...
for mcrypt:
"Y+JgMBdfI7ZYY3M9lJXCtb5Vgu+rWvLBfjug2GLX7uo="
for for openssl:
"Y+JgMBdfI7ZYY3M9lJXCtb5Vgu+rWvLBvte4swdttHY="
Tried using $options to pass OPENSSL_ZERO_PADDING, but passing anything but 1 (OPENSSL_RAW_DATA, or true) results in an empty string ...
Neither using OPENSSL_ZERO_PADDING nor OPENSSL_RAW_DATA | OPENSSL_ZERO_PADDING work... :(
I'm using "OpenSSL 1.0.2g 1 Mar 2016".
Already read this q&a, but it does not help me. Not the only one with padding troubles, but no solution in sight so far. Second answer talks about adding padding to mcrypt call, I would really want to remove padding from openssl encryption call...
mcrypt_encrypt zero-pads input data if it's not a multiple of the blocksize. This leads to ambiguous results if the data itself has trailing zeroes. Apparently OpenSSL doesn't allow you to use zero padding in this case, which explains the false return value.
You can circumvent this by adding the padding manually.
$message = "Lorem ipsum";
$key = "123456789012345678901234";
$iv = "12345678";
$message_padded = $message;
if (strlen($message_padded) % 8) {
$message_padded = str_pad($message_padded,
strlen($message_padded) + 8 - strlen($message_padded) % 8, "\0");
}
$encrypted_mcrypt = mcrypt_encrypt(MCRYPT_3DES, $key,
$message, MCRYPT_MODE_CBC, $iv);
$encrypted_openssl = openssl_encrypt($message_padded, "DES-EDE3-CBC",
$key, OPENSSL_RAW_DATA | OPENSSL_NO_PADDING, $iv);
printf("%s => %s\n", bin2hex($message), bin2hex($encrypted_mcrypt));
printf("%s => %s\n", bin2hex($message_padded), bin2hex($encrypted_openssl));
This prints both as equal.
4c6f72656d20697073756d => c6fed0af15d494e485af3597ad628cec
4c6f72656d20697073756d0000000000 => c6fed0af15d494e485af3597ad628cec
mcrypt_encrypt uses zeroes to pad message to the block size. So you can add zeroes to the tail of your raw data, and then encrypt the block.
Using OPENSSL_RAW_DATA|OPENSSL_ZERO_PADDING should work. If it doesn't, then you can remove padding from the decrypted data by yourself.
Related
I need create multiply search by years. From request I get string like 2017,2018 and then I want get Questions which createdAt, between from start year and end year. I have query builder with part, and I'am not understand why I have this error
if ($paramFetcher->get('years')) {
$orXSearch = $qb->expr()->orX();
$yearData = trim($paramFetcher->get('years'));
foreach (explode(',', $yearData) as $key => $id) {
if (!$id) {
continue;
}
$orXSearch
->add($qb->expr()->between('q.createdAt', ':'.$key.'dateFrom', ':'.$key.'dateTo'));
$date = $this->additionalFunction->validateDateTime($id, 'Y');
$first = clone $date;
$first->setDate($date->format('Y'), 1, 1);
$first->setTime(0, 0, 0);
$last = clone $date;
$last->setDate($date->format('Y'), 12, 31);
$last->setTime(23, 59 , 59);
$qb
->setParameter($key.'dateFrom', $first->format('Y-m-d H:i:s'))
->setParameter($key.'dateTo', $last->format('Y-m-d H:i:s'));
}
$qb->andWhere($orXSearch);
}
error:
symfony Invalid parameter format, : given, but :<name> or ?<num> expected.
In your foreach loop, you’re looping over the result of an explode operation which yields a numeric array, i.e. $key will always have a numeric value.
Hence, your parameter placeholder is colon + number + string, i.e. :1dateFrom. This is not allowed. Either you reference a string value with a colon + string placeholder (:foo), or you reference a numeric value with a question mark + number value (?1).
Your problem is easy to solve: Simply add any letter between the colon and the number, and you’re good:
->add($qb->expr()->between(
'q.createdAt',
':x'.$key.'dateFrom',
':x'.$key.'dateTo'
));
I have successfuly enlisted a user in moodle cohort using core_cohort_add_cohort_members but i am getting a warning in response.Can anybody help me remoce this warning.
Here is the warning i get.
{"warnings":[]}
Here is my code
$fname = 'core_cohort_add_cohort_members';
/// Paramètres
$member = new stdClass();
$member->cohorttype[type]='id';
$member->cohorttype[value]=2;
$member->usertype[type]='id';
$member->usertype[value]=8;
$members = array($member);
$par = array('members' => $members);
$rest_format = 'json';
$Serve_Url = 'localhost/moodle' . '/webservice/rest/server.php'. '?wstoken=' . '72f102312fff135cbb4a301d9c7839ae' .'&wsfunction='. $fname;
require_once('curl.inc');
$Rest_format = ($rest_format == 'json') ? '&moodlewsrestformat=' . $rest_format : '';
$curl = new curl;
//if rest format == 'xml', then we do not add the param for backward compatibility with Moodle < 2.2
$rep = $curl->post($Serve_Url.$Rest_format, $par);
dpm($rep);
The warnings array is empty in your example reply.
If you want to detect this more verbosely, you can always just json_decode() the reply. You should see an empty array there.
So I think it's working just as you wanted.
Turn the keys into strings i.e
$member->cohorttype["type"]='id';
$member->cohorttype["value"]=2;
$member->usertype["type"]='id';
$member->usertype["value"]=8;
Mainly because newer versions of PHP may cause real exceptions because of
unidentified variables(type and value)
That aside as Sebastian Berm stated empty warnings array means no problem
For each post, there is a custom field name "Function", the key/value pair is like this:
Key : Functions
Value : <!--en-->Nourishing Yin and invigorating the vital essence of kidneys.<!--:--><!--tw-->滋陰補腎。<!--:-->
The problem is if I simply use get_post_meta , it return string of both language, how can I get the value based on the language?
I am using qTranslate right now, Thanks.
Updated (the code):
$custom_fields = get_post_custom(get_the_ID());
$function = get_post_custom_values('Functions', get_the_ID());
You can simply fetch the strings considering comments as prefix and suffix -
After you get the custom field value,
e.g.
$function = "<!--en-->Nourishing Yin and invigorating the vital essence of kidneys.<!--:--><!--tw-->滋陰補腎。<!--:-->";
$arr = explode("<!--:-->", $function);
$new_arr = array();
foreach($arr as $a ){
if(!empty($a)){
$lang = str_replace( "-->", "", substr($a, 4, 5) );
$str = substr($a, 9);
$new_arr[$lang] = $str;
}
}
Now $new_arr will have key/value pairs like array(language_code => sentence).
If you do print_r($new_arr);
It will give output as follows:
Array ( [en] => Nourishing Yin and invigorating the vital essence of kidneys. [tw] => 滋陰補腎。 )
Now you can identify the strings using their respective language codes.
I have this Python script to encrypt/decrypt URLs:
# -*- coding: utf-8 -*-
import base64
from operator import itemgetter
class cryptUrl:
def __init__(self):
self.key = 'secret'
def encode(self, str):
enc = []
for i in range(len(str)):
key_c = self.key[i % len(self.key)]
enc_c = chr((ord(str[i]) + ord(key_c)) % 256)
enc.append(enc_c)
return base64.urlsafe_b64encode("".join(enc))
def decode(self, str):
dec = []
str = base64.urlsafe_b64decode(str)
for i in range(len(str)):
key_c = self.key[i % len(self.key)]
dec_c = chr((256 + ord(str[i]) - ord(key_c)) % 256)
dec.append(dec_c)
return "".join(dec)
url = "http://google.com";
print cryptUrl().encode(url.decode('utf-8'))
This works fine. For example the above url is converted to 29nX4p-joszS4czg2JPG4dI= and the decryption brings it back to the URL.
Now i want to convert this to a PHP function. So far encryption is working fine....but decryption is not....and i dont know why.....so far i got this:
function base64_url_encode($input) {
return strtr(base64_encode($input), '+/=', '-_');
}
function base64_url_decode($input) {
return strtr(base64_decode($input), '-_', '+/=');
}
function encode ($str)
{
$key = 'secret';
$enc = array();
for ($i;$i<strlen($str);$i++){
$key_c = $key[$i % strlen($key)];
$enc_c = chr((ord($str[$i]) + ord($key_c)) % 256);
$enc[] = $enc_c;
}
return base64_url_encode(implode($enc));
}
function decode ($str)
{
$key = 'secret';
$dec = array();
$str = base64_url_decode($str);
for ($i;$i<strlen($str);$i++){
$key_c = $key[$i % strlen($key)];
$dec_c = chr((256 + ord($str[$i]) + ord($key_c)) % 256);
$dec[] = $dec_c;
}
return implode($dec);
}
$str = '29nX4p-joszS4czg2JPG4dI=';
echo decode($str);
Now the above decoding prints out : N>:Tý\&™åª—Væ which is not http://google.com :p
Like i said encoding function works though.
Why isnt the decoding working ? What am i missing ?
Btw i cant use any other encoding/decoding function. I have a list of URLs encoded with python and i want to move the whole system to a PHP based site....so i need to decode those URLs with a PHP function instead of python.
(Use this page to execute Python: http://www.compileonline.com/execute_python_online.php)
Double check the syntax of strtr().
I'd suggest you using in in the following way:
strtr(
base64_encode($input),
array(
'+' => '-',
'/' => '_',
'=' => YOUR_REPLACE_CHARACTER
)
)
Make sure you have YOUR_REPLACE_CHARACTER!
Also, I'm sure you'll handle the reverse function, where you need to simply flip the values of the replace array.
I am tasked with i18n-ing our current CMS setup in Drupal.
The problem that I am facing is with use of module_invoke() to place blocks within nodes.
I have managed to string translate blocks, and that is working when a block is placed in a region (block content is successfully translated) using the UI.
However, when a block is injected into a node like such:
$block = module_invoke('block', 'block', 'view', 22); print $block['content'];
It is not getting translated, or even worse, not showing at all.
I have also tried this variation using t(). e.g.:
$block = module_invoke('block', 'block', 'view', 22); print t($block['content']);
to no avail.
Generally speaking I've having a bit of trouble with blocks for i18n. Does anyone have a recommended approach for dealing with blocks in drupal with regards to translating them? I would prefer not to create different blocks for each language.
So .. After digging around in the bowels of Drupal - and much hair pulling .. I've come up with an almost decent solution.
Basically, with this function, I can extract a translated version of a block:
function render_i18n_block($block_id, $region = "hidden"){
if ($list = block_list($region)) {
foreach ($list as $key => $block) {
// $key == <i>module</i>_<i>delta</i>
$key_str = "block_".$block_id;
if ($key_str == $key){
return theme('block', $block);
}
}
}
}
Then, in my node, I simple call:
<?php echo render_i18n_block(<block_id>,<region>); ?>
There can be some issues where your blocks might not be displaying in a region (and therefore you can't pass a region into block_list). For this case, I simply created a region called "hidden" which is not rendered anywhere in my template, but can be used to call block_list.
Finally (and this is the part that I still need to find a good solution for), I discovered that block_list() in: includes/blocks/block.inc has a bit of an issue.
It appears that $theme_key is not reliably set unless block_list() is being called from the theme() function (in includes/themes.inc) .. this causes the SQL to return an empty results set. The SQL looks like this:
$result = db_query(db_rewrite_sql("SELECT DISTINCT b.* FROM {blocks} b LEFT JOIN {blocks_roles} r ON b.module = r.module AND b.delta = r.delta WHERE b.theme = '%s' AND b.status = 1 AND (r.rid IN (". db_placeholders($rids) .") OR r.rid IS NULL) ORDER BY b.region, b.weight, b.module", 'b', 'bid'), array_merge(array($theme_key), $rids));
As you can see, if theme_key is not set, then it will just return an empty result.
For now I am bypassing this by simply adding:
if (!isset($theme_key)){$theme_key="<my_theme_name>";}
in modules/blocks/block.inc::block_list() around line 429 .. I still need to work out a better way to do this.
10 for anyone with suggestions on how I could ensure that $theme_key is set before calling block_list :)
I had exactly the same problem as you, since I was using
$block = module_invoke('block', 'block_view', 'block_id');
print render($block['content']);
to inject the block into my nodes. However, looking up module_invoke in the Drupal reference, I found a comment titled "to render blocks in Drupal 7 better to use Block API", with this code:
function block_render($module, $block_id) {
$block = block_load($module, $block_id);
$block_content = _block_render_blocks(array($block));
$build = _block_get_renderable_array($block_content);
$block_rendered = drupal_render($build);
return $block_rendered;
}
I just un-functioned it to use directly, like so:
$block = block_load('block', 'block_id');
$block_content = _block_render_blocks(array($block));
$build = _block_get_renderable_array($block_content);
print render($build);
And for me it works like a charm. Be aware however that this method prints the block title as well, so maybe you'll want to set it to 'none' in the original language.
Create a function like this
<?php
function stg_allcontent2($allC, $level
= "1") {
global $language; $lang = $language->language;
foreach ($allC as $acKey => $ac) {
if($ac['link']['options']['langcode']
== $lang){ if ($level == "1")
$toR .= "";
if (is_array($ac['below']))
$class="expanded"; else
$class="leaf";
$toR .= "<li class=\"".$class."\">" . l($ac['link']['link_title'], $ac['link']['link_path']) . "</li>";
if ($level != "1") $toR .= ""; if (is_array($ac['below'])) $toR .= "<ul class=\"menu\">".stg_allcontent2($ac['below'], "2")."</ul>"; if ($level == "1") $toR .= ""; }
}
return $toR; } ?>
call like this
<?php echo '<ul class="menu">'; echo stg_allcontent2(menu_tree_all_data($menu_name
= 'menu-header', $item = NULL)); echo '</ul>'; ?>
This may help you: http://drupal-translation.com/content/translating-block-contents#
UPDATE: the t() function allows you to pass in the language code to use.