Forum Discussion

AlexDuncan-b8f1's avatar
AlexDuncan-b8f1
Community Member
31 days ago

hashed filenames in published output

Problem: when storyline files are published, media filenames are replaced with hashed filenames in the published output (a 11-character series of apparently random alphanumerics). We have a search tool to search published output (we use it for content generated by other programs as well) and return the media filenames to us. This is important, as we frequently need to update media. So if we find out that "made-up graphic name.png" is out of date, we can quickly search all our existing courseware to find where we've used it, and replace it.

In the published output, the original filenames and hashed filenames are both mentioned in a hashed-name JS file, and in data.js (both are found in ...[project name]\html5\data\js). However, the correspondence between the original filenames and the hashed filenames is used in an inconsistent manner, and we're having trouble creating a program that will recover the filenames in all circumstances.

Anyone ever dealt with this before? Got any tips?

Thanks...

  • Jürgen_Schoene_'s avatar
    Jürgen_Schoene_
    31 days ago

     

    if you are really precise, the filename is not a hash - it is independent of the content.

    It is generated when the medium is imported - a GUID-4 is generated, e.g. 

    • "06a3dc93-48e9-4ac5-97d2-cec1cd3df540"

    • the guid is then split into its 5 blocks
    • the last two blocks are removed
    • the first three are put together backwards
    • the whole thing is now converted to base62
    • at the end, an “R” is added in front and the appropriate file extension is added

    • result: "R5wlhTmswUhH.png"

     

    if you now parse “story/story.xml” in the .story file, you can find out the mapping between the original file name and the generated file name

  • I made a tool that automagically creates a base course from Googlesheets, PSDs, Illustrator files and/or images. This works perfect for quite some authoring tools ( Lectora and Captivate ), however due to Storyline's closed environment where each asset gets hashed it is almost impossible to get working. When you change the .story of a Storyline file to .zip, you can unzip it and check/search the content. However its hashed/confuscated the moment you import it into Storyline. Would be great if Articulate opens this up somewhat more for developers. Maybe the upcoming Javascript API gives better access.

    • Jürgen_Schoene_'s avatar
      Jürgen_Schoene_
      Community Member

       

      if you are really precise, the filename is not a hash - it is independent of the content.

      It is generated when the medium is imported - a GUID-4 is generated, e.g. 

      • "06a3dc93-48e9-4ac5-97d2-cec1cd3df540"

      • the guid is then split into its 5 blocks
      • the last two blocks are removed
      • the first three are put together backwards
      • the whole thing is now converted to base62
      • at the end, an “R” is added in front and the appropriate file extension is added

      • result: "R5wlhTmswUhH.png"

       

      if you now parse “story/story.xml” in the .story file, you can find out the mapping between the original file name and the generated file name

      • MathNotermans-9's avatar
        MathNotermans-9
        Community Member

        Thats nice Jurgen. So with this logic you could  regenerate the filename and thus generate a working .story from other tools... im really gonna see if i can get this working in my setup.

  • Jurgen - thanks for your response. I'm looking at a .story file, and I've found a filename for one of my graphics that's been converted (with the "R" added, as you indicated). However, all of the text around it is nonsense to me. I see nothing that looks like a GUID. For example, the text immediately following is "¢ (                      lWUPl\4¸Ëâîîîî‹XÜ-¸;,î¶Ü5¸Cðஂ† Á‚Ûý÷xU÷ðUWMOÍÃ753Ýqšê".

    There's some aspect of your instruction above that I'm not following. Can you clarify a bit? In particular, where should I find the GUID relative to the filename in the .story file?

  • this file, what you found was a ".xml.rel" file - this don't help you

    • rename the .story to .zip
    • extract the zip
    • you need "./story/story.xml"

    if you have a good xml editor, open story.xml

    or

    • download Notepad++ and install (or use the portable version)
    • enable the XML Tools

    open story/story.xml

    • all important infos are in line 1 !!!
    • beautify the xml

    now you can see the infos for all imported media files, e.g.

    g = "3181b10f-8857-43eb-bfe9-7d95d79938b4"
    
    displayName = "png-32.png"
    • storyline uses "g" (GUID-4) to generate the new filename
    • "displayName" is the original filename

    with the algorithm from above

    • "3181b10f-8857-43eb-bfe9-7d95d79938b4" => "R5pXHZ6Y4dCB.png"

    result

    • "R5pXHZ6Y4dCB.png" => "png-32.png"

     

     

     

    • Nathan_Hilliard's avatar
      Nathan_Hilliard
      Community Member

      Thanks Jürgen for the great insight.

      As an interesting aside, after looking at the story.xml content I discovered that you can also directly access (at least read) the built-in storyline variables from JS by using the listed propPath values.

      GetPlayer().GetVar("_playerVars.currentSlideId");

      Never thought you could do that. You learn something new everyday.🙂

    • AlexDuncan-b8f1's avatar
      AlexDuncan-b8f1
      Community Member

      Jurgen - this works. Thanks for taking the time to provide a more in-depth explanation.

      I'm amazed that someone (you?) went to the trouble to figure this out. It would never have crossed my mind to extract things by renaming the story file to a zip. This is amazing.

      We're going to see about automating the process. Should be fun.

      Thanks again!

  • I really love these discussions and discoveries as by Jurgen and Nathan. Although tempted to experiment further, i do wait a bit till the new Javascript API is available. As things probably change a lot then ;-)